OpenCV边缘提取

来源:互联网 发布:重庆理工大学网络教育 编辑:程序博客网 时间:2024/05/29 13:16

边缘检测是图像处理中的一种传统算法,可以用来做物体检测。偶然间看到一个例子,形态学操作实为巧妙,稍作分析记录下来,同时分享给像我一样的小白。代码经过整理如下:

#include<iostream>#define max(a,b) a>b?a:busing namespace std;int main(){cv::Mat pupil_image = cv::imread("test.jpg",0);cv::Mat binary_img, spec_mask, kernel;cv::Mat histogram;int histSize;histSize = 256;float range[] = { 0, 256 }; const float* histRange = { range };int max_intensity = 40, lowest_spike_index = 255, highest_spike_index =0;cv::calcHist(&pupil_image, 1, 0, cv::Mat(), histogram, 1, &histSize, &histRange, true, false);for (int i = 0; i < histogram.rows; i++) {const float intensity = histogram.at<float>(i, 0);if (intensity > 40) {max_intensity = max(intensity, max_intensity);lowest_spike_index = min(lowest_spike_index, i);highest_spike_index = max(highest_spike_index, i);}}cv::inRange(pupil_image, cv::Scalar(0), cv::Scalar(lowest_spike_index + 20), binary_img);    kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));cv::dilate(binary_img, binary_img, kernel, cv::Point(-1, -1), 2);cv::inRange(pupil_image, cv::Scalar(0), cv::Scalar(highest_spike_index - 20), spec_mask);   cv::erode(spec_mask, spec_mask, kernel);kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(9, 9));//下面开始处理原图cv::morphologyEx(pupil_image, pupil_image, cv::MORPH_OPEN, kernel);cv::medianBlur(pupil_image, pupil_image, 3);cv::Mat edges;cv::Canny(pupil_image, edges, 15, 40, 3);(cv::min)(edges, spec_mask, edges);(cv::min)(edges, binary_img, edges);cv::imshow("out", edges);cv::waitKey();return 0;}
网上随便找了两张图,运行结果如下:

每幅图从左至右分别是原图、直接求边缘、进行开操作和滤波后求边缘、通过形态学处理过滤后的结果。

通过形态学过滤,可以过滤掉了高亮度部分,剩下图像较暗区域。在某些具体运用中,能起到很大的作用。例子中两个cv::min很巧妙的过滤掉高光(spec_mask)周围边缘,保留较暗(binary_img)部分。剩下的是边缘两侧都不是高亮度(低于高亮度域值),且有一侧是较暗区域(低于较暗域值)。

通过灰度直方图可以找到感兴趣的灰度区域域值,选择感兴趣的边缘。


原创粉丝点击