Escribí este código para el suavizado de la curva .
Se tarda 5 puntos próximos a un punto y los agrega y promedios de ella .

/* Smoothing */
void smoothing(vector<Point2D> &a)
{
    //How many neighbours to smooth
    int NO_OF_NEIGHBOURS=10;
    vector<Point2D> tmp=a;
    for(int i=0;i<a.size();i++)
    {

        if(i+NO_OF_NEIGHBOURS+1<a.size())
        {
            for(int j=1;j<NO_OF_NEIGHBOURS;j++)
            {
                a.at(i).x+=a.at(i+j).x;
                a.at(i).y+=a.at(i+j).y;
            }
            a.at(i).x/=NO_OF_NEIGHBOURS;
            a.at(i).y/=NO_OF_NEIGHBOURS;

        }
        else
        {
            for(int j=1;j<NO_OF_NEIGHBOURS;j++)
            {
                a.at(i).x+=tmp.at(i-j).x;
                a.at(i).y+=tmp.at(i-j).y;
            }
            a.at(i).x/=NO_OF_NEIGHBOURS;
            a.at(i).y/=NO_OF_NEIGHBOURS;
        }

    }

}

Pero me da valores muy altos para cada punto, en lugar de los valores similares a los del punto anterior . La forma se maximiza mucho , lo que va mal en este algoritmo ?

  • Uso += y /= hace el código más legible (y tiene menos llamadas a at(i)).
  • ¿Qué sucede si que se alimentan de datos simple, donde los resultados son previsibles, y depurarlo?
  • j es cero, por lo que en el interior de los bucles no está suavizando con ]i, i+NO_OF_NEIGHBOURS], pero con [i, i+NO_OF_NEIGHBOURS]
  • Que hizo el truco , gracias 🙂 .
  • Tener en cuenta que en la cláusula else se accede a los elementos que ya estaban alterados por su algoritmo de suavizado! También tenga en cuenta que el promedio de un punto con sus vecinos, usted tiene que dividir la suma por 1 + NO_OF_NEIGHBORS, como el punto en sí está contenida dentro de esta suma.
  • yo sé que yo soy el acceso a la ya alterada puntos , no hay una mejor alternativa para incluir la condición de contorno ?
  • Usted podría utilizar una copia del vector original para leer.
  • hmm, eso tiene sentido .
  • ¿La última edición de realizar todo ok ? Todavía tengo que dividir por 1+NO_OF_NEIGHBORS ? .Sé que es suavizado basado en NO_OF_NEIGHBORS-1, pero eso está bien .
  • Se olvidó de usar tmp en el if cláusula y la + 1 en la condición parece un poco raro. La división por NO_OF_NEIGHBOURS o 1 + NO_OF_NEIGHBOURS es sólo cuestión de entender. Usted simplemente necesita saber cuántos puntos en la suma que se obtenga el promedio. En su editada ejemplo NO_OF_NEIGHBOURS (sin + 1) es la correcta divisor.
  • creo que no es importante el uso de tmp en si , porque no es la evaluación de los elementos que ya están suaves .

InformationsquelleAutor rajat | 2012-10-19

6 Comentarios

  1. 3

    en el siguiente bloque:

                for(int j=0;j<NO_OF_NEIGHBOURS;j++)
                {
                    a.at(i).x=a.at(i).x+a.at(i+j).x;
                    a.at(i).y=a.at(i).y+a.at(i+j).y;
                }

    para cada vecino de agregar una.en(i)’s x e y, respectivamente, del prójimo valores.

    entiendo correctamente, debería ser algo como esto.

                for(int j=0;j<NO_OF_NEIGHBOURS;j++)
                {
                    a.at(i).x += a.at(i+j+1).x
                    a.at(i).y += a.at(i+j+1).y
                }
    • Cuando se utiliza este cambio NO_OF_NEIGHBOURS será uno más que el número real de los vecinos de usa.
    • a la derecha, la condición debe ser j<NO_OF_NEIGHBOURS+1, para ser más claros, j debe comenzar desde 0, una.en el(i+j) debe ser un.en el(i+j+1).
    • La variable se denomina NO_OF_NEIGHBOURS significado el número de vecinos liso con. Dada su corregido bucle j tendrá NO_OF_NEIGHBOURS - 1 valores diferentes, lo que significa que NO_OF_NEIGHBOURS - 1 vecinos se suavizan, que es un poco de sentido común para el nombre.
  2. 10

    Lo que parece que tenemos aquí es un bajo-patas arriba la implementación de un FIR (finite impulse response) filtro que implementa un vagón de la función de la ventana. Pensar el problema en términos de DSP, usted necesita el filtro de entrada vector con NO_OF_NEIGHBOURS igual FIR coeficientes de que cada uno tiene un valor de 1/NO_OF_NEIGHBOURS. Normalmente es mejor utilizar establecido un algoritmo en lugar de reinventar la rueda.

    Aquí es bastante desaliñado aplicación que me resolvieron rápidamente que los filtros dobles. Usted puede modificar fácilmente para filtrar el tipo de datos. La demo muestra de filtrado de un par de ciclos de un aumento de la sierra de la función (0,.25,.5,1) sólo para fines de demostración. Compila, así que usted puede jugar con él.

    #include <iostream>
    #include <vector>
    using namespace std;
    class boxFIR
    {
    int numCoeffs; //MUST be > 0
    vector<double> b; //Filter coefficients
    vector<double> m; //Filter memories
    public:
    boxFIR(int _numCoeffs) :
    numCoeffs(_numCoeffs)
    {
    if (numCoeffs<1)
    numCoeffs = 1; //Must be > 0 or bad stuff happens
    double val = 1./numCoeffs;
    for (int ii=0; ii<numCoeffs; ++ii) {
    b.push_back(val);
    m.push_back(0.);
    }
    }    
    void filter(vector<double> &a)
    {
    double output;
    for (int nn=0; nn<a.size(); ++nn)
    {
    //Apply smoothing filter to signal
    output = 0;
    m[0] = a[nn];
    for (int ii=0; ii<numCoeffs; ++ii) {
    output+=b[ii]*m[ii];
    }
    //Reshuffle memories
    for (int ii = numCoeffs-1; ii!=0; --ii) {
    m[ii] = m[ii-1];
    }                        
    a[nn] = output;
    }
    }
    };
    int main(int argc, const char * argv[])
    {
    boxFIR box(1); //If this is 1, then no filtering happens, use bigger ints for more smoothing
    //Make a rising saw function for demo
    vector<double> a;
    a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
    a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
    a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
    a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
    box.filter(a);
    for (int nn=0; nn<a.size(); ++nn)
    {
    cout << a[nn] << endl;
    }
    }

    El número de coeficientes del filtro de usar esta línea para ver una vez más suavizada de salida. Con sólo 1 filtro de coeficiente, no hay ningún suavizado.

    boxFIR box(1);

    El código es lo suficientemente flexible que puede incluso cambiar la ventana de forma que si te gusta. Hacer esto mediante la modificación de los coeficientes definidos en el constructor.

    Nota: Esto le dará un poco diferente al de salida para su aplicación como esta es una causal de filtro (sólo depende de la corriente de la muestra y ejemplos anteriores). Su implementación no es causal como se ve más adelante en el tiempo al futuro muestras para hacer el promedio, y por eso necesita las instrucciones condicionales para la situación en la que están cerca del final de su vector. Si desea una salida como lo que usted está tratando de hacer con su filtro usando este algoritmo, ejecute el su vector a través de este algoritmo a la inversa (Esto funciona bien siempre y cuando la ventana de la función es simétrica). De esa manera usted puede obtener una salida similar sin la desagradable condicional parte del algoritmo.

    • Yo no tenía ni idea sobre el Filtro FIR , yo sólo quería suavizar los puntos .La época de dominio de las implementaciones de filtros FIR mejor que este algoritmo ?
    • Absolutamente, if declaraciones en el medio de una función de filtrado son desagradables como el que usted tiene que tener un algoritmo para tus límites. Ver mis ediciones
    • YEY. Alguien le dio a este un +1. Esta ES la solución óptima. Se quejan se quejan se quejan.
    • Un inversa pasar podría ser útil para evitar la distorsión de fase (en ese caso es un cero distorsión de fase del filtro).
  3. 3

    Filtrado es bueno para la «memoria» de suavizado. Este es el reverso de pasar por el learnvst del respuesta, para evitar distorsión de fase:

    for (int i = a.size(); i > 0; --i)
    {
    //Apply smoothing filter to signal
    output = 0;
    m[m.size() - 1] = a[i - 1];
    for (int j = numCoeffs; j > 0; --j) 
    output += b[j - 1] * m[j - 1];
    //Reshuffle memories
    for (int j = 0; j != numCoeffs; ++j) 
    m[j] = m[j + 1];
    a[i - 1] = output;
    }

    Más sobre cero distorsión de fase, filtro FIR en MATLAB: http://www.mathworks.com/help/signal/ref/filtfilt.html

  4. 1

    El actual valor del punto se usa dos veces: una vez porque utiliza += y una vez si y==0. Así que usted está construyendo la suma de por ejemplo 6 puntos, pero sólo se divide por 5. Este problema es tanto el SI y OTRO caso. También: se debe comprobar que el vector es el tiempo suficiente de lo contrario su PERSONA-caso leerá en índices negativos.

    Siguientes no es un problema en sí mismo, sino sólo un pensamiento: ¿Ha considerado el uso de un algoritmo que sólo toca todos los puntos dos veces?: Usted puede almacenar un temporal x-y-valor (inicializado a ser idénticos a los del primer punto), luego de la visita a cada momento que acaba de añadir el nuevo punto y restar la muy antigua de punto si es que más allá de su NEIGHBOURS de la espalda. Mantenga esta «suma de ejecución» se actualiza cada punto y almacenar este valor dividido por el NEIGHBOURS-número en el nuevo punto.

    • Gracias por la sugerencia acerca de la comprobación de la longitud del vector.Estoy teniendo un tiempo difícil entender el algoritmo alternativo . Se puede explicar de la misma en los términos de la pseudo código ?
    • Ohk,entendido, gracias 🙂 . el momento en que la complejidad no es una preocupación en mi problema ya que tengo un vector con sólo 128 puntos .
  5. 1

    De hacer, además con el punto en sí mismo cuando usted necesita tomar vecino puntos – acaba de desplazamiento índice de 1:

    for(int j=0;j<NO_OF_NEIGHBOURS;j++)
    {
    a.at(i).x += a.at(i+j+1).x
    a.at(i).y += a.at(i+j+1).y
    }
  6. 0

    Esto funciona muy bien para mí:

    for (i = 0; i < lenInput; i++)
    {
    float x = 0;
    for (int j = -neighbours; j <= neighbours; j++)
    {
    x += input[(i + j <= 0) || (i + j >= lenInput) ? i : i + j];
    }
    output[i] = x / (neighbours * 2 + 1);
    }

Dejar respuesta

Please enter your comment!
Please enter your name here