Qt 图像处理(四)sobel算子与图像卷积

sobel算子与图像卷积

图像卷积

//图像的卷积运算
/*
 * QImage *image               输入图像
 * QImage &TemplateImg         输出图像
 * int nTempH                  模板的height = (nTempH -1)3x3的模板
 * int nTempW                  模板的width =(nTempW - 1) 3x3的模板
 * int nTempMY,int nTempMX     模板中心点的位置
 * float *pfArray              模板数组
 * float fCorf                 加权系数
*/
void MainWindow::Template(QImage *image,QImage &TemplateImg,int nTempH,int nTempW,int nTempMY,int nTempMX,float *pfArray,float fCorf)
{

    QColor oldColor;

    //扫描图像就行卷积运算
    for(int i = nTempMY; i< (image->height() - (nTempH-nTempMY)) + 1; i++)
    {
        for(int j = nTempMX; j < (image->width() - (nTempW-nTempMX)) + 1; j++)
        {
            //i的中心点
            float fResult = 0;

            for(int k = 0; k < nTempH; k++)
            {
                for(int l = 0; l < nTempW; l++)
                {
                    oldColor = QColor(image->pixel((j + l - nTempMX), (i + k - nTempMY)));
                    //计算累加和
                    fResult += oldColor.red() * pfArray[k * nTempW + 1];
                }
            }

            //系数
            fResult *= fCorf;

            //去绝对值
            fResult = (float)fabs(fResult);

            BYTE byte;

            if(fResult>255)
            {
                byte = 255;
            }
            else
            {
                byte = fResult + 0.5;
            }

            TemplateImg.setPixel(j,i, qRgb(byte, byte, byte));

        }
    }
}

sobel算子

/*
 * QImage *image               输入图像
 * QImage &SobelIma            输出图像
 * int modle                   0:为计算x y方向的梯度值  1:计算x方向的梯度  2:计算y方向的梯度  3:计算45度方向的梯度  4:计算135度方向的梯度
 * bool pdouble                是否返回梯度的方向与梯度的幅值
*/
double* MainWindow::Sobel_gradiant(QImage *image,QImage &SobelIma,int modle,bool pdouble)
{


    float sobel_y[9] = {-1,-2,-1,
                         0,0,0,
                         1,2,1
                        };

    float sobel_x[9] = {-1,0,1,
                         -2,0,2,
                         -1,0,1
                        };

    float sobel_135[9] = {0,1,2
                          -1,0,1,
                          -2,-1,0
                         };

    float sobel_45[9] = {-2,-1,0,
                          -1,0,1,
                          0,1,2
                         };

    int width = image->width();
    //int height = image->height();
    int allnum = image->width()*image->height();

    double *arr_point_X  = new double[allnum];
    memset(arr_point_X,0,allnum * sizeof(double));

    double *arr_point_Y  = new double[allnum];
    memset(arr_point_Y,0,allnum * sizeof(double));

    double *angle  = new double[allnum];
    memset(angle,0,allnum * sizeof(double));

    double *Amplitude  = new double[allnum];
    memset(Amplitude,0,allnum * sizeof(double));


    QColor oldColor1,oldColor2,oldColor3,oldColor4,oldColor5,oldColor6;
    QColor v_oldColor1,v_oldColor2,v_oldColor3,v_oldColor4,v_oldColor5,v_oldColor6;

    //选择梯度模式
    switch (modle) {

        case 0:


            double kerne1_Result,kerne2_Result,all_Result;
            int result;

            for(int j=1;jheight()-1;j++)
            {
                for(int i=1; iwidth()-1;i++)
                {
                    //垂直梯度
                    oldColor1 = QColor(image->pixel(i-1,j-1));
                    oldColor2 = QColor(image->pixel(i,j-1));
                    oldColor3 = QColor(image->pixel(i+1,j-1));

                    oldColor4 = QColor(image->pixel(i-1,j+1));
                    oldColor5 = QColor(image->pixel(i,j+1));
                    oldColor6 = QColor(image->pixel(i+1,j+1));

                    kerne1_Result = (oldColor1.red()+oldColor2.red()*2+oldColor3.red())-(oldColor4.red()+oldColor5.red()*2+oldColor6.red());


                    //水平梯度
                    v_oldColor1 = QColor(image->pixel(i-1,j-1));
                    v_oldColor2 = QColor(image->pixel(i-1,j));
                    v_oldColor3 = QColor(image->pixel(i-1,j+1));

                    v_oldColor4 = QColor(image->pixel(i+1,j-1));
                    v_oldColor5 = QColor(image->pixel(i+1,j));
                    v_oldColor6 = QColor(image->pixel(i+1,j+1));

                    kerne2_Result = (v_oldColor1.red()+v_oldColor2.red()*2+v_oldColor3.red())-(v_oldColor4.red()+v_oldColor5.red()*2+v_oldColor6.red());
                    //all_Result = abs(kerne2_Result)+abs(kerne1_Result);
                    all_Result = sqrt((kerne2_Result*kerne2_Result)+(kerne1_Result*kerne1_Result));

                    //保存xy方向的梯度
                    arr_point_X[j*width + i] = kerne2_Result;
                    arr_point_Y[j*width + i] = kerne1_Result;

                    Amplitude[j*width + i] = all_Result;
                    angle[j*width + i] = atan2(kerne1_Result,kerne2_Result);

                if(all_Result>255){
                    result = 255;
                }else {
                    result = all_Result + 0.5;
                }

                SobelIma.setPixel(i,j, qRgb(result, result, result));

                }
            }

               // this->Show_Image(SobelIma);

              break;

        case 1:
                this->Template(image,SobelIma,3,3,1,1,sobel_x,1);

                //this->Show_Image(SobelIma);
             break;

        case 2:
            this->Template(image,SobelIma,3,3,1,1,sobel_y,1);
            //this->Show_Image(SobelIma);
             break;

        case 3:
            this->Template(image,SobelIma,3,3,1,1,sobel_45,1);
            //this->Show_Image(SobelIma);
            break;

        case 4:
            this->Template(image,SobelIma,3,3,1,1,sobel_135,1);
            //this->Show_Image(SobelIma);

            break;

        default:
            break;
    }

你可能感兴趣的:(图像处理,图像处理,Qt)