C+中的Canny过滤器+; 我尝试在C++中实现Canny滤波器。我希望得到这样的结果

C+中的Canny过滤器+; 我尝试在C++中实现Canny滤波器。我希望得到这样的结果 ,c++,opencv,C++,Opencv,但我得到了结果 非最大化抑制后的图像与输出图像似乎脱节,不实 我的代码如下 #include<stdio.h> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <cmath> #include <iostream> #include <opencv2\opencv.hpp> #include <

但我得到了结果

非最大化抑制后的图像与输出图像似乎脱节,不实

我的代码如下

#include<stdio.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cmath>
#include <iostream>
#include <opencv2\opencv.hpp>
#include <time.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

int main(){
    cv::Mat inImage = cv::imread("C:\\Users\\DUY\\Desktop\\lena.jpg");
    cv::Mat outImage;
    cv::Mat rgbaImage;
    cv::Mat greyImage;
    cv::Mat blurImage;
    cv::Mat edgeMag;
    cv::Mat edgeDir;
    cv::Mat suppress;
    cv::cvtColor(inImage, rgbaImage, CV_BGR2RGBA);
    int numRows = rgbaImage.rows;
    int numCols = rgbaImage.cols;


    cv::cvtColor(rgbaImage, greyImage, CV_RGBA2GRAY);
    blurImage.create(numRows, numCols, CV_8UC1);
    edgeMag.create(numRows, numCols, CV_8UC1);
    edgeDir.create(numRows, numCols, CV_8UC1);
    suppress.create(numRows, numCols, CV_8UC1);
    outImage.create(numRows, numCols, CV_8UC1);


    clock_t start, end;
    start = clock();
    //------------------- Gaussian filter-----------------------//
    cv::Mat gaussianMask = (cv::Mat_<int>(5,5) << 2, 4, 5, 4, 2, 4, 9, 12,   9, 4, 5, 12, 15, 12, 5, 
                                            4, 9, 12, 9, 4, 2, 4, 5, 4, 2);

    for(int index_x = 2; index_x < numCols - 2; index_x++){
        for(int index_y = 2; index_y < numRows - 2; index_y++){
            float value = 0;
            for(int i = -2; i <= 2 ; i++){
                for(int j = -2; j <= 2; j++){
                    value = value + greyImage.at<unsigned char>(index_x+j, index_y+i) * gaussianMask.at<int>(i+2,j+2) ;
                }
            }

             value = value/159;

             blurImage.at<unsigned char>(index_x, index_y) = (unsigned char) value;
        }
    }
    end = clock();
    //------------------ Find the intensity gradient of the image---------------------//
    cv::Mat GxMask = (cv::Mat_<int>(3,3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);
    cv::Mat GyMask = (cv::Mat_<int>(3,3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);

    for(int index_x = 1;index_x<numCols -1;index_x++){
       for(int index_y=1;index_y<numRows -1; index_y++){

           float mag = 0;

           float Gx = 0, Gy = 0;
           for(int i=-1;i<=1;i++){
               for(int j=-1;j<=1;j++){

                    Gx = Gx + blurImage.at<unsigned char>(index_x+i, index_y+j) * GxMask.at<int>(i+1,j+1);
                    Gy = Gy + blurImage.at<unsigned char>(index_x+i, index_y+j) * GyMask.at<int>(i+1,j+1);
               }
           }

           mag = sqrt(Gx*Gx + Gy*Gy);
           edgeMag.at<unsigned char>(index_x, index_y) = mag;
           float thisAngle = (atan2(Gx, Gy)/3.14159)*180;
           float newAngle;
           if ( ( (thisAngle < 22.5) && (thisAngle > -22.5) ) || (thisAngle > 157.5) || (thisAngle < -157.5) )
                newAngle = 0;
           if ( ( (thisAngle > 22.5) && (thisAngle < 67.5) ) || ( (thisAngle < -112.5) && (thisAngle > -157.5) ) )
               newAngle = 45;
           if ( ( (thisAngle > 67.5) && (thisAngle < 112.5) ) || ( (thisAngle < -67.5) && (thisAngle > -112.5) ) )
               newAngle = 90;
           if ( ( (thisAngle > 112.5) && (thisAngle < 157.5) ) || ( (thisAngle < -22.5) && (thisAngle > -67.5) ) )
           newAngle = 135;
           edgeDir.at<unsigned char>(index_x, index_y) = newAngle;
       }
    }
    //--------------------------Non-maximum suppression------------------------//
    for(int i = 1;i<numCols -1;i++){
       for(int j=1;j<numRows -1; j++){
            if((edgeDir.at<unsigned char>(i,j) == 0 && edgeMag.at<unsigned char>(i,j) > edgeMag.at<unsigned char>(i+1,j) && edgeMag.at<unsigned char>(i,j) > edgeMag.at<unsigned char>(i-1,j))||
            (edgeDir.at<unsigned char>(i,j) == 90 && edgeMag.at<unsigned char>(i,j) > edgeMag.at<unsigned char>(i,j+1) && edgeMag.at<unsigned char>(i,j) > edgeMag.at<unsigned char>(i,j-1))||
            (edgeDir.at<unsigned char>(i,j) == 45 && edgeMag.at<unsigned char>(i,j) > edgeMag.at<unsigned char>(i+1,j-1) && edgeMag.at<unsigned char>(i,j) > edgeMag.at<unsigned char>(i-1,j+1))||
            (edgeDir.at<unsigned char>(i,j) == 135 && edgeMag.at<unsigned char>(i,j) > edgeMag.at<unsigned char>(i+1,j+1) && edgeMag.at<unsigned char>(i,j) > edgeMag.at<unsigned char>(i-1,j-1))){
                    suppress.at<unsigned char>(i,j) = edgeMag.at<unsigned char>(i,j);   
            }
             else{
                suppress.at<unsigned char>(i,j) = 0;
            }
        }
    }
    //-------------------------Hysteresis---------------------------//
    for(int i = 1;i<numCols -1;i++){
        for(int j=1;j<numRows -1; j++){
            int upperThreshold = 60;
            int lowerThreshold = 30;
            if(suppress.at<unsigned char>(i,j) > upperThreshold){
                outImage.at<unsigned char>(i,j) = 255;
            }
            if(suppress.at<unsigned char>(i,j) < lowerThreshold){
                outImage.at<unsigned char>(i,j)  = 0;
            }
        }
    }

    for(int i = 1;i<numCols -1;i++){
        for(int j=1;j<numRows -1; j++){
            int upperThreshold = 60;
            int lowerThreshold = 30;
            if(suppress.at<unsigned char>(i,j) < upperThreshold && suppress.at<unsigned char>(i,j) > lowerThreshold){
                for(int m = -1; m <= 1; m++){
                    for(int n = -1; n <= 1; n++){
                        if(outImage.at<unsigned char>(i+n,j+m) == 255){
                            outImage.at<unsigned char>(i,j) = 255;
                            break;
                        }
                    }
                }
            }
        }
    }


    float time = ((float)(end-start))/CLOCKS_PER_SEC*1000;
    printf("function: %f ms\n", time);
    //-----------------show image-------------------//
    cv::imshow("raw", inImage);
    cv::imshow("suppress", suppress);
    cv::imshow("out",outImage);
    cv::waitKey();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“cuda_runtime.h”
#包括“设备启动参数.h”
int main(){
cv::Mat inImage=cv::imread(“C:\\Users\\DUY\\Desktop\\lena.jpg”);
cv::Mat outImage;
cv::Mat rgbaImage;
cv::Mat greyImage;
cv::模糊图像;
cv::Mat edgeMag;
cv::Mat edgeDir;
cv::Mat抑制;
cv::CVT颜色(inImage、rgbaImage、cv_BGR2RGBA);
int numRows=rgbaImage.rows;
int numCols=rgbaImage.cols;
cv::CVT颜色(rgbaImage、greyImage、cv_RGBA2GRAY);
创建(numRows、numCols、CV_8UC1);
创建(numRows、numCols、CV_8UC1);
创建(numRows、numCols、CV_8UC1);
抑制.create(numRows、numCols、CV_8UC1);
创建(numRows、numCols、CV_8UC1);
时钟开始、结束;
开始=时钟();
//-------------------高斯滤波器-----------------------//
cv::Mat gaussianMask=(cv::Mat_u5,5)边标记在(i,j+1)和边标记在(i,j)>边标记在(i,j-1))||
(在(i,j)=45和(i,j)处的边缘标记>在(i+1,j-1)处的边缘标记>在(i,j)处的边缘标记>在(i-1,j+1)处的边缘标记)||
(edgeDir.at(i,j)==135&&edgeMag.at(i,j)>edgeMag.at(i+1,j+1)&&edgeMag.at(i,j)>edgeMag.at(i-1,j-1))){
抑制(i,j)=边缘标记(i,j);
}
否则{
抑制。at(i,j)=0;
}
}
}
//-------------------------迟滞---------------------------//
对于(int i=1;i
  • 你的高斯核应该被校准为1
  • 5x5对于该高斯核可能太小(对于更大的高斯核,例如11x11,您可以使用更低的树结构,具有更好的信噪比)
  • 滞后部分似乎也有问题。我没有详细检查您的代码,但是对于滞后,您需要实现一个递归过程,在强边附近的弱边(>thres_low)之后,我在您的代码中看不到这种递归调用

如果你使用OpenCV,你可以使用Canny滤波器。为什么不在OpenCV中使用实现的Canny?我想用C++来理解算法^ ^,但是结果不是我所期望的。你能帮助我吗?谢谢^ ^ ^