1

I need help with my project. I read color image(source image) from disk and my task is to apply blur to this image only where Canny function detect edges in this image. So detection of edges is without problems, as you can see in attached images (Top left corner image - Edge Image). I applied 4 steps from related questions this and this.

Probably steps 1-3 are correct as you can see in attached image. The first image is showing detected edges, the second shows previous image dilated, the third picture shows blurred second image and copied source image to this image. But at the last step I want to copy this image into final image (source image) to achieve that detected edges will be blurred. But when I use copyTo function from OpenCV library the result does not have blurred edges which Canny function detects as you can see in picture Result (right bottom corner image). Can you help me please what I am doing bad?

#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

Big thanks for everybody for your help and advices.

pilot205
  • 19
  • 2
  • 1
    Please don't post links to images of your code, we require code as text that reproduces your issue – EdChum Nov 10 '17 at 09:02
  • "the result is bad" is no proper description. we don't know the input so how can we judge the output? – Piglet Nov 10 '17 at 09:07

1 Answers1

0

When you copy back the blurred edge in your original image, you are using the wrong mask. detected_edges contains the output of the Canny detector (only some sparse pixels). The non-zeros pixels if the mask indicate which pixels of the source image can be copied to the destination. The image blurred contains only the blurred edge, and the rest of the pixels are black. So I think you can directly use it as a mask for the copy.

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

Keep in mind that the mask needs to be of type CV_8U. It seems that in your example this is the case. If not, you can use the following code to create an image that is black except where the pixels in blurred are not null.

blurred.copyTo(src, (blurred != 0));     //4
cedrou
  • 2,780
  • 1
  • 18
  • 23