如何模糊Cv :: Mat图像只有Canny函数使用OpenCV检测此图像的边缘

时间:2017-11-10 09:00:35

标签: c++ opencv image-processing blur edges

我的项目需要帮助。我从磁盘读取彩色图像(源图像),我的任务是仅在Canny功能检测到此图像中的边缘时将模糊应用于此图像。因此,您可以在附加图像(左上角图像 - 边缘图像)中看到边缘检测没有问题。 我从相关问题中应用了4个步骤 thisthis

正如您在附图中看到的那样,步骤1-3可能是正确的。第一个图像显示检测到的边缘,第二个图像显示前一个图像扩大,第三个图像显示模糊的第二个图像和复制的源图像到此图像。但在最后一步,我想将此图像复制到最终图像(源图像),以实现检测到的边缘将模糊。但是当我使用OpenCV库中的copyTo函数时,结果没有Canny函数检测到的模糊边缘,如图所示(右下角图像)。能帮助我,请问我做得不好吗?

#include <cstdlib>
#include <iostream>
#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

Mat src, src_gray;
Mat detected_edges;
Mat blurred;

int edgeTresh = 1;
int lowThreshold;
int const max_lowThreshold = 100;
int ratio = 3;
int kernel_size = 3;
char* window_name = "Edge Image";
char* window_name2 = "Dilated";
char* window_name3 = "Blurred";
char* window_name4 = "Result";

void CannyThreshold(int, void*)
{
   //reducing noise
   blur(src_gray, detected_edges, Size(3,3));

   //Canny function for detection of edges
   Canny(detected_edges,detected_edges, lowThreshold,lowThreshold*ratio, kernel_size);
   //show detected edges in source image
   imshow(window_name, detected_edges);

   //4 steps from stack owerflow
   dilate(detected_edges, blurred, Mat()); //1
   imshow(window_name2, blurred);

   src.copyTo(blurred,blurred);            //2
   blur(blurred, blurred ,Size(10,10));    //3
   imshow(window_name3, blurred);

   //here can by a problem when I copy image from step 3 to source image with detected_edges mask.
   blurred.copyTo(src,detected_edges);     //4
   imshow(window_name4, src);              //final image 
}

int main(int argc, char *argv[])
{
   //reading image
   src = cv::imread("/home/ja/FCS02/FCS02_3/imageReading/drevo.png");
   if(!src.data)
       return -1;

   //convert to gray
   cvtColor(src,src_gray,CV_BGR2GRAY);

   //windows for showing each step image
   namedWindow(window_name,CV_WINDOW_NORMAL);
   namedWindow(window_name2,CV_WINDOW_NORMAL);
   namedWindow(window_name3,CV_WINDOW_NORMAL);
   namedWindow(window_name4,CV_WINDOW_NORMAL);

   //trackbar
   createTrackbar("Min Threshold:",window_name, &lowThreshold, max_lowThreshold,CannyThreshold);

   //detection of edges
   CannyThreshold(0,0);

   cv::waitKey(300000);

   return EXIT_SUCCESS;
}

Source Image where I want to blur only edges

Results of my code

This image shows what I want

非常感谢大家的帮助和建议。

1 个答案:

答案 0 :(得分:0)

复印原始图像中的模糊边缘时,使用的是错误的蒙版。 detected_edges包含Canny检测器的输出(仅一些稀疏像素)。如果掩码指示源图像的哪些像素可以复制到目的地,则非零像素。图像blurred仅包含模糊边缘,其余像素为黑色。所以我认为你可以直接用它作为副本的掩码。

blurred.copyTo(src, blurred);     //4

请记住,蒙版需要是CV_8U类型。似乎在你的例子中就是这种情况。如果没有,您可以使用以下代码创建一个黑色图像,除非blurred中的像素不为空。

blurred.copyTo(src, (blurred != 0));     //4