【QtOpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContoursdrawContours】

本文主要是介绍【QtOpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContoursdrawContours】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、函数介绍
    • 1、HoughLinesP
    • 2、HoughCircles
    • 3、findContours
    • 4、 drawContours
  • 二、演示
    • 1、GUI
    • 2、代码实现
  • 总结


前言

越来越多的开发人员选择基于开源的Qt框架与OpenCV来实现界面和算法,其原因不单单是无版权问题,更多是两个社区的发展蓬勃,可用来学习的资料与例程特别丰富。以下是关于利用Qt构建GUI并使用OpenCV中的HoughLinesP/HoughCircles/findContours&drawContours函数进行图像检测。
软件版本:Qt-5.12.0/OpenCV-4.5.3
平台:Windows10/11–64


一、函数介绍

1、HoughLinesP

函数原型
cv::HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 )

参数解释
image:输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里;
Iines:经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,每一条线由具有四个元素的矢量(x_1,y_1, x_2, y_2) 表示,其中,(x_1, y_1)和(x_2, y_2) 是是每个检测到的线段的结束点;
rho:以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径;
theta:以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度;
threshold:累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中;
minLineLength:有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来;
maxLineGap:有默认值0,允许将同一行点与点之间连接起来的最大的距离;

2、HoughCircles

函数原型
cv::HoughCircles(InputArray image,OutputArray circles, int method, double dp, double minDist, double param1=100,double param2=100, int minRadius=0, int maxRadius=0 )

参数解释
image输入图像,即源图像,需为8位的灰度单通道图像;
circles:经过调用HoughCircles函数后此参数存储了检测到的圆的输出矢量,每个矢量由包含了3个元素的浮点矢量(x, y, radius)表示;
method:即使用的检测方法,目前OpenCV中就霍夫梯度法一种可以使用,它的标识符为CV_HOUGH_GRADIENT,在此参数处填这个标识符即可;
dp:用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,且此参数允许创建一个比输入图像分辨率低的累加器。上述文字不好理解的话,来看例子吧。例如,如果dp= 1时,累加器和输入图像具有相同的分辨率。如果dp=2,累加器便有输入图像一半那么大的宽度和高度;
minDist:为霍夫变换检测到的圆的圆心之间的最小距离,即让我们的算法能明显区分的两个不同圆之间的最小距离。这个参数如果太小的话,多个相邻的圆可能被错误地检测成了一个重合的圆。反之,这个参数设置太大的话,某些圆就不能被检测出来了;
param1:有默认值100。它是第三个参数method设置的检测方法的对应的参数。对当前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示传递给canny边缘检测算子的高阈值,而低阈值为高阈值的一半;
param2:也有默认值100。它是第三个参数method设置的检测方法的对应的参数。对当前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示在检测阶段圆心的累加器阈值。它越小的话,就可以检测到更多根本不存在的圆,而它越大的话,能通过检测的圆就更加接近完美的圆形了;
minRadius:有默认值0,表示圆半径的最小值;
maxRadius:也有默认值0,表示圆半径的最大值;

3、findContours

函数原型:
cv::findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy,
int mode, int method, Point offset = Point());

参数解释
image:单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像;
contours:contours定义为“vector contours”,是一个双重向量(向量内每个元素保存了一组由连续的Point构成的点的集合的向量),每一组点集就是一个轮廓,有多少轮廓,contours就有多少元素;
hierarchy:hierarchy定义为“vector hierarchy”,Vec4i的定义:typedef Vec<int, 4> Vec4i;(向量内每个元素都包含了4个int型变量),所以从定义上看,hierarchy是一个向量,向量内每个元素都是一个包含4个int型的数组。向量hierarchy内的元素和轮廓向量contours内的元素是一一对应的,向量的容量相同。hierarchy内每个元素的4个int型变量是hierarchy[i][0] ~ hierarchy[i][3],分别表示当前轮廓 i 的后一个轮廓、前一个轮廓、父轮廓和内嵌轮廓的编号索引。如果当前轮廓没有对应的后一个轮廓、前一个轮廓、父轮廓和内嵌轮廓,则相应的hierarchy[i][*]被置为-1。
mode:定义轮廓的检索模式,取值如下:

CV_RETR_EXTERNAL:只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略;
CV_RETR_LIST:检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1,具体下文会讲到;
CV_RETR_CCOMP: 检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层;
CV_RETR_TREE: 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。

method:定义轮廓的近似方法,取值如下:

CV_CHAIN_APPROX_NONE:保存物体边界上所有连续的轮廓点到contours向量内;
CV_CHAIN_APPROX_SIMPLE:仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留;
CV_CHAIN_APPROX_TC89_L1:使用teh-Chinl chain 近似算法;
CV_CHAIN_APPROX_TC89_KCOS:使用teh-Chinl chain 近似算法。

offset:Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,并且Point还可以是负值!

4、 drawContours

函数原型
cv::drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar & color, int thickness = 1, int lineType = LINE_8, InputArray hierarchy = noArray(), int maxLevel = INT_MAX, Point offset = Point())

参数解释
image:目标图像
contours:输入的所有轮廓(每个轮廓以点集的方式存储)
contoursIdx:指定绘制轮廓的下标(若为负数,则绘制所有轮廓)
color:绘制轮廓的颜色
thickness:绘制轮廓的线的宽度(若为负数,则填充轮廓内部)
lineType:绘制轮廓的线型(4连通、8连通或者反锯齿)
hierarchy:关于层级的可选信息,仅用于当你想要绘制部分轮廓的时候
maxLevel:绘制轮廓的最大层级,若为0,则仅仅绘制指定的轮廓;若为1,则绘制该轮廓及其内嵌轮廓,若为2,则绘制该轮廓、其内嵌轮廓以及内嵌轮廓的内嵌轮廓,依次类推。该参数只有在有层级信息输入时才被考虑。
offset:可选的轮廓偏移参数,所有的轮廓将会进行指定的偏移

当thickness = FILLED,即使没有提供层级信息也可以正确处理带孔洞的连通域情况(分析轮廓时采用奇偶规则),但如果是单独检索的轮廓合并则可能会出现错误的情况,该情况下则需要分开处理。

二、演示

1、GUI

在这里插入图片描述
如上图创建Operator的QComboBox控件进行函数选择,Action的功能按钮QPushButton,对当前窗口进行检测,并输出状态信息。

2、代码实现

HoughLinesP/HoughCircles/findContours&drawContours实现代码:
geometryBtn的clicked()槽函数

void MainWindow::on_geometryBtn_clicked()
{std::size_t numView = ui->tabWidget->currentIndex() % 3;if (dispMat[numView]->empty()){outputInfo(2, tr("Please make sure the Mat exist!"));return;}if (dispMat[numView]->channels() == 3){cv::cvtColor(*dispMat[numView], *dispMat[numView], cv::COLOR_RGB2GRAY);}tmpMat->zeros(dispMat[numView]->size(), \dispMat[numView]->type());cv::GaussianBlur(*dispMat[numView], *dispMat[numView], cv::Size(3, 3), \0, 0, cv::BORDER_DEFAULT);int operatorType = ui->geometryCombo->currentIndex();	// 0: line, 1: circle, 2: contoursswitch (operatorType){case 0:{int cannyThresh = ui->cannyThreshSlider->value();int lineThresh = ui->lineThreshSlider->value();std::vector<cv::Vec4i> lines;cv::Canny(*dispMat[numView], *tmpMat, cannyThresh, \cannyThresh * 2, 3);cv::HoughLinesP(*tmpMat, lines, 1, CV_PI/180, lineThresh, 50, 10);for (size_t i = 0; i < lines.size(); i++){cv::Vec4i l = lines[i];cv::line(*tmpMat, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), \cv::Scalar(0, 0, 255), 1, 1, 1);}outputInfo(1, tr("Lines done."));break;}case 1:{int circleThresh = ui->circleThreshSlider->value();std::vector<cv::Vec3f> circles;double startTime = static_cast<double>(cv::getTickCount());cv::HoughCircles(*dispMat[numView], circles, cv::HOUGH_GRADIENT, \1, dispMat[numView]->rows / 16, \circleThresh, circleThresh/2, \0, 0);double timeCost = (static_cast<double>(cv::getTickCount()) - \startTime) / cv::getTickFrequency();QString costTime = "Cost time: " + QString::number(timeCost);outputInfo(1, costTime);for (size_t i = 0; i < circles.size(); i++){cv::Point center(cvRound(circles[i][0]), \cvRound(circles[i][1]));int radius = cvRound(circles[i][2]);cv::circle(*tmpMat, center, 3, \cv::Scalar(0, 255, 0), -1, 8, 0);cv::circle(*tmpMat, center, radius, \cv::Scalar(0, 0, 255), 3, 8, 0);}outputInfo(1, tr("Circles done."));break;}case 2:{cv::RNG rng(12345);int cannyThresh = ui->cannyThreshSlider->value();cv::Canny(*dispMat[numView], *tmpMat, cannyThresh, \cannyThresh * 2, 3);std::vector<std::vector<cv::Point>> contours;std::vector<cv::Vec4i> hierarchy;cv::findContours(*tmpMat, contours, hierarchy, \cv::RETR_TREE, \cv::CHAIN_APPROX_SIMPLE, \cv::Point(0, 0));std::vector<std::vector<cv::Point>> contoursPoly(contours.size());std::vector<cv::Rect> boundRect(contours.size());std::vector<cv::Point2f> center(contours.size());std::vector<float> radius(contours.size());for (size_t i = 0; i < contours.size(); i++){cv::approxPolyDP(cv::Mat(contours[i]), contoursPoly[i], 3, true);boundRect[i] = cv::boundingRect(cv::Mat(contoursPoly[i]));minEnclosingCircle(contoursPoly[i], center[i], radius[i]);}for (size_t i = 0; i < contours.size(); i++){cv::Scalar color = cv::Scalar(rng.uniform(0, 255), \rng.uniform(0, 255), \rng.uniform(0, 255));cv::drawContours(*tmpMat, contoursPoly, static_cast<int>(i), \color, 1, 8, \std::vector<cv::Vec4i>(), 0, \cv::Point());cv::rectangle(*tmpMat, boundRect[i].tl(), \boundRect[i].br(), \color, 2, 8, 0);cv::circle(*tmpMat, center[i], static_cast<int>(radius[i]), \color, 2, 8, 0);}outputInfo(1, tr("Contours done."));break;}}if (ui->geometryChkBox->isChecked()){*dispMat[numView] = tmpMat->clone();cvtMatPixmap(dispMat, dispPixmap, numView);}else{if (tmpMat->channels() == 3){QImage tmpImage = QImage(tmpMat->data, tmpMat->cols,tmpMat->rows, \static_cast<int>(tmpMat->step), \QImage::Format_RGB888);dispPixmap[numView]->setPixmap(QPixmap::fromImage(tmpImage.rgbSwapped()));}else{QImage tmpImage = QImage(tmpMat->data, tmpMat->cols,tmpMat->rows, \static_cast<int>(tmpMat->step), \QImage::Format_Grayscale8);dispPixmap[numView]->setPixmap(QPixmap::fromImage(tmpImage.rgbSwapped()));}}
}

总结

以上是关于利用Qt进行GUI构建并使用OpenCV中的 HoughLinesP/HoughCircles/findContours&drawContours函数进行图像检测。
参考:
链接:前期https://blog.csdn.net/richard_yuu/article/details/128037970
其中疑问或错误,欢迎联系交流,

这篇关于【QtOpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContoursdrawContours】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/179075

相关文章

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

Verybot之OpenCV应用一:安装与图像采集测试

在Verybot上安装OpenCV是很简单的,只需要执行:         sudo apt-get update         sudo apt-get install libopencv-dev         sudo apt-get install python-opencv         下面就对安装好的OpenCV进行一下测试,编写一个通过USB摄像头采

[数据集][目标检测]血细胞检测数据集VOC+YOLO格式2757张4类别

数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2757 标注数量(xml文件个数):2757 标注数量(txt文件个数):2757 标注类别数:4 标注类别名称:["Platelets","RBC","WBC","sickle cell"] 每个类别标注的框数:

Temu官方宣导务必将所有的点位材料进行检测-RSL资质检测

关于饰品类产品合规问题宣导: 产品法规RSL要求 RSL测试是根据REACH法规及附录17的要求进行测试。REACH法规是欧洲一项重要的法规,其中包含许多对化学物质进行限制的规定和高度关注物质。 为了确保珠宝首饰的安全性,欧盟REACH法规规定,珠宝首饰上架各大电商平台前必须进行RSLReport(欧盟禁限用化学物质检测报告)资质认证,以确保产品不含对人体有害的化学物质。 RSL-铅,

【python计算机视觉编程——7.图像搜索】

python计算机视觉编程——7.图像搜索 7.图像搜索7.1 基于内容的图像检索(CBIR)从文本挖掘中获取灵感——矢量空间模型(BOW表示模型)7.2 视觉单词**思想****特征提取**: 创建词汇7.3 图像索引7.3.1 建立数据库7.3.2 添加图像 7.4 在数据库中搜索图像7.4.1 利用索引获取获选图像7.4.2 用一幅图像进行查询7.4.3 确定对比基准并绘制结果 7.

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法(KNN)8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特征8.4.3 多类支持向量机8.4.4 提取单元格并识别字符8.4.5 图像校正