栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ OpenCV实践:复杂划痕背景下检测缺陷

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ OpenCV实践:复杂划痕背景下检测缺陷

文章目录
  • 前言
  • 1. 检测步骤
  • 2. C++ OpenCV实现
  • 3. 结果展示:
  • 总结
  • 参考


前言

最近在51Halcon中看到一条有意思的求助帖子,有热心朋友给出了Halcon的解决方法,这里给出C++ OpenCV的解决方法。


1. 检测步骤

Halcon实现(引用https://www.51halcon.com/thread-1173-1-2.html):

看到检测图像以及想要检测的目标(绿色实线闭合区域),我们知道,要检测的区域的区分度不高,这里给出个人实现思路:检测区域位于圆形的中心,而圆形中心区域亮度比周边要高,我们可以先分割出中心亮度高的区域,然后在这一分割出的区域进行检测目标,提取出目标轮廓。

2. C++ OpenCV实现
#include 
#include 
#include 
#include 
#include 

using namespace cv;

int main()
{
	std::string strImgFile = "C:\Temp\common\Workspace\Opencv\images\detect_defect_with_complex_background.bmp";
	Mat mSrc = imread(strImgFile);
	CV_Assert(!mSrc.empty());

	Mat mGray;
	cvtColor(mSrc, mGray, COLOR_BGR2GRAY);
	CV_Assert(!mGray.empty());

	Mat mThresh;
	threshold(mGray, mThresh, 0, 255, THRESH_BINARY | THRESH_OTSU);
	CV_Assert(!mThresh.empty());

	imshow("thresh", mThresh);

	Mat mCenterLightArea;
	threshold(mGray, mCenterLightArea, 200, 255, THRESH_BINARY);
	CV_Assert(!mCenterLightArea.empty());

	imshow("center", mCenterLightArea);

	Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11));
	Mat mOpen;
	morphologyEx(mCenterLightArea, mOpen, MORPH_OPEN, kernel);
	CV_Assert(!mOpen.empty());

	imshow("open1", mOpen);

	morphologyEx(mOpen, mOpen, MORPH_DILATE, kernel, Point(-1, -1), 7);
	 
	imshow("open2", mOpen); 

	std::vector> contours;
	findContours(mOpen, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
	Point2f center = { 0 };
	float	radius = 0;

	for (int i = 0; i < contours.size(); i++)
	{
		Point2f tempCenter = { 0 };
		float tempRadius = 0;
		minEnclosingCircle(contours[i], tempCenter, tempRadius);

		if (tempRadius > radius)
		{
			radius = tempRadius;
			center = tempCenter;
		}
	}

	Mat mMask = Mat::zeros(mOpen.size(), mOpen.type());
	CV_Assert(!mMask.empty());

	circle(mMask, Point(int(center.x + 0.5), int(center.y + 0.5)), int(radius + 0.5), 255, -1);

	imshow("mask", mMask);

	Mat mCenterArea = mGray & mMask;
	CV_Assert(!mCenterArea.empty());

	imshow("center", mCenterArea);

	Mat mResult;
	threshold(mCenterArea, mResult, 10, 255, THRESH_BINARY_INV | THRESH_OTSU);
	CV_Assert(!mResult.empty());
	imshow("result", mResult);

	contours.clear();
	findContours(mResult, contours, RETR_TREE, CHAIN_APPROX_NONE);

	for (int i = 0; i < contours.size(); i++)
	{
		double area = contourArea(contours[i]);
		if (area > 1000 && area < 10000)
		{
			drawContours(mSrc, contours, i, Scalar(0, 0, 255));
		}
	}

	imshow("Final Result", mSrc);

	waitKey(0);
	destroyAllWindows();

	system("pause");
	return 0;
}
3. 结果展示:

原图:

OpenCV实现:

Halcon实现(引用https://www.51halcon.com/thread-1173-1-2.html):


总结

本人的方法,只针对特定的原始图像,没法验证通用性,个人感觉很繁琐,没有Halcon简单方便,如果有大神提供简单的OpenCV实现方法,欢迎赐教,谢谢!

参考

https://www.51halcon.com/thread-1173-1-2.html

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/290048.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号