我目前正在进行一个图像处理项目,通过 C++ 使用 OpenCV 和 Visual Studio 检测表面上的裂缝。我已经尝试编写我的程序,但目前我被卡住了,因为我很难在图像中的噪声和防止“裂缝”由于 dilate() 操作而缩小之间取得平衡。我对 OpenCV 完全陌生,之前只用 C 编写过代码,所以我希望你能耐心并慢慢解释。:)
我目前正在处理下面的照片,该照片取自 Google 图片,其父 URL 为:http: //www.newindianexpress.com/states/kerala/article1330634.ece
我将在下面输入我的代码:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/photo/photo.hpp"
#include "highgui.h"
#include <cv.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
using namespace std;
int main( int argc, char** argv ){
//Declarations
double alpha; /**< Simple contrast control */ //unused
int beta; /**< Simple brightness control */ //unused
float minVal;
float maxVal;
Mat bw_img;
Mat contrast1;
Mat gaussian_img;
Mat filtered_img;
Mat weighted_img;
Mat adaptive_img;
//Loads image from file and put image matrix into "original_photo"
Mat original_img = imread ("crack.jpg", 1);
//Convert color-to-gray image
cvtColor( original_img, bw_img, CV_BGR2GRAY );
//imshow("bw_img", bw_img);
//Gaussian filtering
int i = 7;
GaussianBlur(bw_img,gaussian_img,Size(i,i),0,0);
imshow("gaussian_img", gaussian_img);
//HPF kernel
Mat kernel = (Mat_<float>(3,3) <<
0, -1, 0,
-1, 5, -1,
0, -1, 0);
filter2D(gaussian_img, filtered_img,-1, kernel, Point(-1,-1),0);
//Extract high-frequency features, e.g. edges show up.
addWeighted(filtered_img, 1.5, bw_img, -0.5, 0,weighted_img);
imshow("weighted_img",weighted_img);
//Perform adaptive thresholding
adaptiveThreshold(weighted_img,adaptive_img,255,ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 51, 20);
imshow("adaptive_img",adaptive_img);
//Construct structuring element
Mat struc_elem = getStructuringElement(MORPH_RECT,Size(5,5));
//Perform erosion first
Mat eroded_img;
erode(adaptive_img,eroded_img,struc_elem);
imshow("eroded_img",eroded_img);
//Perform dilation next
Mat dilate_img;
dilate(eroded_img,dilate_img,struc_elem);
imshow("dilate_img",dilate_img);
double otsu_thresh_val = threshold(dilate_img, dilate_img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
double high_thresh_val = otsu_thresh_val,lower_thresh_val = otsu_thresh_val * 0.5;
Mat cannyOP;
Canny( dilate_img, cannyOP, lower_thresh_val, high_thresh_val );
imshow("cannyOP",cannyOP);
//wait for long long time
int c = waitKey(20000000000000);
//if you get impatient, end program
if (c == 27)
{
return 0;
}
}
到目前为止,我得到的图像相当嘈杂,经过腐蚀和膨胀后有很多黑色斑点。我稍后会发布照片,因为我没有足够的声誉来发布更多链接。对不起。
我试图将 AdaptiveThreshold() 函数中的 blockSize 和 C 值从当前的 51/20 增加到 101/50。噪音大部分都被消除了,但裂缝特征的尺寸减小了。此图稍后发布,称为图 2。
我还尝试维护 blockSize 和 C 的adaptiveThreshold() 数字,并尝试执行先膨胀后腐蚀。最终的图像噪点少了一些,虽然还是有黑点,但是裂痕变得有些不连续。此图稍后发布,称为图 3。
请问,我应该如何通过adaptiveThreshold() 函数或erode() 和dilate() 函数去除噪声而不导致裂缝变薄或变宽?
这是因为如果裂纹较薄,裂纹将在最终输出图像中完全“消失”。
谢谢!:)