Как размыть изображение Cv :: Mat только там, где функция Canny обнаруживает края этого изображения с помощью OpenCV

Мне нужна помощь с моим проектом. Я читаю цветное изображение (исходное изображение) с диска, и моя задача — применить размытие к этому изображению только там, где функция Canny обнаруживает края в этом изображении. Таким образом, обнаружение краев происходит без проблем, как вы можете видеть на прикрепленных изображениях (верхний левый угол изображения — Edge Image).
Я применил 4 шага от связанных вопросов
этот а также этот.

Вероятно, шаги 1-3 являются правильными, как вы можете видеть на прилагаемом изображении. Первое изображение показывает обнаруженные края, второе показывает расширенное предыдущее изображение, третье изображение показывает размытое второе изображение и скопированное исходное изображение в это изображение. Но на последнем шаге я хочу скопировать это изображение в конечное изображение (исходное изображение), чтобы добиться того, что обнаруженные края будут размыты. Но когда я использую функцию copyTo из библиотеки OpenCV, результат не имеет размытых краев, которые обнаруживает функция 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;
}

Исходное изображение, где я хочу размыть только края

Результаты моего кода

Это изображение показывает, что я хочу

Большое спасибо всем за вашу помощь и советы.

1

Решение

Когда вы копируете размытый край исходного изображения, вы используете неправильную маску. detected_edges содержит выходные данные детектора Канни (только несколько разреженных пикселей). Ненулевые пиксели, если маска указывает, какие пиксели исходного изображения могут быть скопированы в место назначения. Изображение blurred содержит только размытый край, а остальные пиксели черного цвета. Поэтому я думаю, что вы можете напрямую использовать его в качестве маски для копии.

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

Имейте в виду, что маска должна быть типа CV_8U. Кажется, что в вашем примере это так. Если нет, вы можете использовать следующий код, чтобы создать изображение черного цвета, кроме случаев, когда пиксели в blurred не являются нулевыми

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]