一、查找并绘制轮廓
/// 载入原始图,必须以二值图模式载入
cv::Mat image = cv::imread("E:/OpencvStudyTest/4.png", cv::ImreadModes::IMREAD_GRAYSCALE);
cv::imshow("image", image);
/// 初始化结果图
cv::Mat dstImage = cv::Mat::zeros(image.rows, image.cols, CV_8UC3);
/// 取大于阈值119的部分
image = image > 119;
cv::imshow("srcimage", image);
/// 定义轮廓与层次结构
std::vector<std::vector<cv::Point>> contouts;
std::vector<cv::Vec4i> hierarchy;
/// 查找轮廓
cv::findContours(image, contouts, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
/// 遍历所有顶层的轮廓,以随机颜色绘制
for(int index = 0; index >= 0; index = hierarchy[index][0])
{
cv::Scalar color(rand() & 255, rand() & 255, rand() & 255);
cv::drawContours(dstImage, contouts, index, color, cv::FILLED, 8, hierarchy);
}
cv::imshow("dstImage", dstImage);
二、寻找物体凸包 convexHull
/// 加载源图像
cv::Mat dstImage;
cv::Mat image = cv::imread("E:/OpencvStudyTest/6.png", cv::ImreadModes::IMREAD_COLOR);
cv::imshow("image", image);
/// 转换成灰度图并模糊降噪
cv::cvtColor(image, dstImage, cv::COLOR_BGR2GRAY);
cv::blur(dstImage, dstImage, cv::Size(3, 3));
cv::imshow("dstImage", dstImage);
cv::threshold(dstImage, dstImage, 100, 255, cv::THRESH_BINARY);
/// 定义轮廓与层次结构
std::vector<std::vector<cv::Point>> contouts;
std::vector<cv::Vec4i> hierarchy;
/// 查找轮廓
cv::findContours(dstImage, contouts, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
/// 遍历每个轮廓,寻找其凸包
std::vector<std::vector<cv::Point>> hull(contouts.size());
for(int i = 0; i < contouts.size(); i++)
{
cv::convexHull(cv::Mat(contouts[i]), hull[i], false);
}
/// 绘制出轮廓机器凸包
cv::RNG rng(12345);
cv::Mat drawing = cv::Mat::zeros(dstImage.size(), CV_8UC3);
for(int i = 0; i < contouts.size(); i++)
{
cv::Scalar color = cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
cv::drawContours(drawing, contouts, i, color, 1, 8, std::vector<cv::Vec4i>(), 0, cv::Point());
cv::drawContours(drawing, hull, i, color, 1, 8, std::vector<cv::Vec4i>(), 0, cv::Point());
}
cv::imshow("drawing", drawing);
三、图像修复
cv::Mat imageSource = cv::imread("E:/OpencvStudyTest/6.png");
if (!imageSource.data)
{
return -1;
}
cv::imshow("原图", imageSource);
cv::Mat imageGray;
//转换为灰度图
cv::cvtColor(imageSource, imageGray, CV_RGB2GRAY, 0);
cv::Mat imageMask = cv::Mat(imageSource.size(), CV_8UC1, cv::Scalar::all(0));
//通过阈值处理生成Mask
cv::threshold(imageGray, imageMask, 240, 255, CV_THRESH_BINARY);
cv::Mat Kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
//对Mask膨胀处理,增加Mask面积
cv::dilate(imageMask, imageMask, Kernel);
//图像修复
cv::inpaint(imageSource, imageMask, imageSource, 5, cv::INPAINT_TELEA);
cv::imshow("imageMask", imageMask);
cv::imshow("imageSource", imageSource);
四、模板匹配 matchTemplate
cv::Mat m_srcImage = cv::imread("E:/OpencvStudyTest/6.png", cv::ImreadModes::IMREAD_COLOR);
cv::Mat m_tempImage = cv::imread("E:/OpencvStudyTest/61.png", cv::ImreadModes::IMREAD_COLOR);
cv::Mat m_resultImage;
int m_nMatchMethod = cv::TM_SQDIFF;
int m_nMaxTrackbarNum = 2;
cv::Mat srcImage;
m_srcImage.copyTo(srcImage);
/// 初始化用于结果输出的矩阵
int resultImage_rows = m_srcImage.rows - m_tempImage.rows + 1;
int resultImage_cols = m_srcImage.cols - m_tempImage.cols + 1;
m_resultImage.create(resultImage_rows, resultImage_cols, CV_32FC1);
/// 进行匹配和标准化
cv::matchTemplate(m_srcImage, m_tempImage, m_resultImage, m_nMatchMethod);
cv::normalize(m_resultImage, m_resultImage, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
/// minMaxLoc定位最匹配位置
double minValue;
double maxValue;
cv::Point minLocation;
cv::Point maxLocation;
cv::Point matchLocation;
minMaxLoc(m_resultImage, &minValue, &maxValue, &minLocation, &maxLocation, cv::Mat());
/// TM_SQDIFF TM_SQDIFF_NORMED 数值越小,匹配度越高,其他的反之
if (m_nMatchMethod == cv::TM_SQDIFF || m_nMatchMethod == cv::TM_SQDIFF_NORMED)
{
matchLocation = minLocation;
}
else
{
matchLocation = maxLocation;
}
/// 绘制出矩形并显示结果
cv::rectangle(m_srcImage, matchLocation, cv::Point(matchLocation.x + m_tempImage.cols, matchLocation.y + m_tempImage.rows), cv::Scalar(0, 0, 255), 2, 8, 0);
cv::rectangle(m_resultImage, matchLocation, cv::Point(matchLocation.x + m_tempImage.cols, matchLocation.y + m_tempImage.rows), cv::Scalar(0, 0, 255), 2, 8, 0);
cv::imshow("m_srcImage", m_srcImage);
cv::imshow("m_resultImage", m_resultImage);