今天主要是研究另一个比较综合的例子。上一个例子只是简单地检测两个平行直线的线段长度和平行线之间的距离,主要应用了直线细化、霍夫变换等主要手段,那么这一次,我们来对三角形进行处理,对于初学者来说,这样一个三角形图片是经典的:
那么问题来了:
1. 求该三角形的周长
2. 求该三角形的面积
实际上这两个问题就是一个问题:三角形的位置信息?如果我们能得到三角形的三个顶点坐标,那么实际上我们就可以掌握这个三角形所有的信息。于是,我们将这个问题演化成这样一个问题:
求三角形三个顶点的坐标
我们不妨来整理一下思路:
1.该图像噪声比较明显,而且属于椒盐噪声,比较适合用中值滤波得到交清晰的图像;
2.进行边缘检测,对于相对来说比较复杂的图像,我们考虑用经典实用的canny算法进行边缘检测;
3.如果边缘存在厚度,我们要进行边缘细化,这张图边缘黑白分界明显,目测没有必要细化;
4.霍夫变换得到三条直线信息。想要得到线段范围信息,只能采用PPHT方法。
如果顺利的话,四步就能够得到我们想要的结果。那我们看看这样做的效果如何把:
Step1:滤波(在此之前转为灰度图像,此处略)
cvSmooth(gray, middle, CV_MEDIAN, 5, 5);
--------->
Step2:边缘检测
cvCanny(middle, canny, 80, 160);
可以看出,不需要边缘细化
Step3:霍夫变换
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines;
lines = cvHoughLines2(canny, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI / 180, 100, 100, 2000);
int n = 0;
for (int i = 0; i < lines->total; ++i)
{
CvPoint* point = (CvPoint*)cvGetSeqElem(lines, i);
cvCircle(result, point[0], 3, CV_RGB(0, 255, 0));
cvCircle(result, point[1], 3, CV_RGB(0, 255, 0));
cvLine(result, point[0], point[1], CV_RGB(0, 255, 0));
n++;
}
我们可以看到,整体的检测效果还是不错的,但是三角形的顶点检测不一,也就是说三个边长并没有完全检测出来,有漏检测的问题。这个实际上是调参数很难弥补的问题,三条边长检测总会存在误差,所以我们要想办法来解决这个问题。
我们发现,虽然顶点没有检测得很好,但是直线方向检测的非常准确,如果我们能作出这三条直线,求出三条直线的交点,我们就可以完美地得到三角形的顶点,如图:
程序如下:
//这是找两条直线的交点的函数
CvPoint FindPoint(double k1, double b1, int judge1, double k2, double b2, int judge2)
{
CvPoint point;
if (judge1 == 0 && judge2 == 1)
{//第一条直线斜率不存在
point.x = k1;
point.y = k2 * point.x + b2;
}
else if (judge1 == 1 && judge2 == 0)
{
point.x = k2;
point.y = k1 * point.x + b1;
}
else if (judge1 == 0 && judge2 == 0)
{
point.x = 0;
point.y = 0;
}
else
{
point.x = (int)((b2 - b1) / (k1 - k2));
point.y = (int)(k1 * point.x + b1);
}
return point;
}
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines;
lines = cvHoughLines2(canny, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI / 180, 100, 100, 2000);
int n = 0;
double k[3];//保存斜率值
double b[3];//保存截距值
double judge[3];//保存是否斜率不存在的判断值
for (int i = 0; i < lines->total; ++i)
{
CvPoint* point = (CvPoint*)cvGetSeqElem(lines, i);
if (point[0].x == point[1].x)//斜率不存在
{
k[i] = point[0].x;
b[i] = point[0].x;//保存x的值,便于函数计算
judge[i] = 0;//斜率不存在
}
else
{
judge[i] = 1;//斜率存在
//计算斜率
double k0 = (double)(point[0].y - point[1].y) / (double)(point[0].x - point[1].x);
//计算截距
double b0 = (double)(point[0].x * point[1].y - point[1].x * point[0].y) / (double)(point[0].x - point[1].x);
k[i] = k0;
b[i] = b0;
}
n++;
}
std::cout << n << endl;
//找三角形的三个顶点位置
CvPoint last1, last2, last3;
last1 = FindPoint(k[0], b[0], judge[0], k[1], b[1], judge[1]);
last2 = FindPoint(k[0], b[0], judge[0], k[2], b[2], judge[2]);
last3 = FindPoint(k[2], b[2], judge[2], k[1], b[1], judge[1]);
cvCircle(result, last1, 3, CV_RGB(255, 0, 0));
cvCircle(result, last2, 3, CV_RGB(255, 0, 0));
cvCircle(result, last3, 3, CV_RGB(255, 0, 0));
cvLine(result, last1, last2, CV_RGB(0, 255, 0));
cvLine(result, last1, last3, CV_RGB(0, 255, 0));
cvLine(result, last3, last2, CV_RGB(0, 255, 0));
得到检测结果如下:
是不是很不错呢。
得到了三个顶点信息后,那么周长、面积什么都是小意思了。
<!--EndFragment-->
相关推荐
在本压缩包“OpenCV-MinGW-Build-OpenCV-4.5.2-x64.zip”中,提供的是一份已经针对MinGW编译器优化的OpenCV 4.5.2版本,适用于64位Windows系统。 OpenCV 4.5.2是该库的一个稳定版本,它包含了众多新特性和性能提升...
OpenCV-MinGW-Build-OpenCV-4.5.0-with-contrib
赠送jar包:opencv-4.5.5-1.5.7.jar; 赠送原API文档:opencv-4.5.5-1.5.7-javadoc.jar; 赠送源代码:opencv-4.5.5-1.5.7-sources.jar; 赠送Maven依赖信息文件:opencv-4.5.5-1.5.7.pom; 包含翻译后的API文档:...
赠送jar包:opencv-4.5.5-1.5.7.jar; 赠送原API文档:opencv-4.5.5-1.5.7-javadoc.jar; 赠送源代码:opencv-4.5.5-1.5.7-sources.jar; 赠送Maven依赖信息文件:opencv-4.5.5-1.5.7.pom; 包含翻译后的API文档:...
赠送jar包:opencv-4.5.1-1.5.5.jar; 赠送原API文档:opencv-4.5.1-1.5.5-javadoc.jar; 赠送源代码:opencv-4.5.1-1.5.5-sources.jar; 赠送Maven依赖信息文件:opencv-4.5.1-1.5.5.pom; 包含翻译后的API文档:...
赠送jar包:opencv-4.5.1-1.5.5.jar; 赠送原API文档:opencv-4.5.1-1.5.5-javadoc.jar; 赠送源代码:opencv-4.5.1-1.5.5-sources.jar; 赠送Maven依赖信息文件:opencv-4.5.1-1.5.5.pom; 包含翻译后的API文档:...
这个压缩包"OpenCV-MinGW-Build-OpenCV-4.5.0-with-contrib-32bit.zip"是专为在Windows环境下使用MinGW编译器进行C++开发而准备的。MinGW(Minimalist GNU for Windows)是一个小型的GNU开发工具集,它提供了一个不...
opencv-4.5.5-opencv-contrib-4.5.5-以及其他OpenCV配置需要的(安装包) opencv-4.5.5-vc14_vc15.exe opencv_contrib-4.5.5.zip cmake-3.24.0-rc1-windows-x86_64.msi jdk-17_windows-x64_bin.msi VTK-8.2.0.zip
opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 ...
opencv-4.5.4-android-sdk .zip
opencv-4.5.5-vc14_vc15.exe opencv_contrib-4.5.5.zip cmake-3.24.0-rc1-windows-x86_64.msi jdk-17_windows-x64_bin.msi VTK-8.2.0.zip
最新的版本“opencv-4.5.3-android-sdk.zip”专为Android平台设计,提供了丰富的API和功能,使得开发者能够在Android设备上实现复杂的图像处理算法。 1. **OpenCV介绍**: OpenCV是一个跨平台的计算机视觉库,由...
3. **贡献模块**(opencv_contrib):包含了额外的模块,如Xfeatures2d(特征检测和描述符),ximgproc(图像处理算法),xobjdetect(对象检测),xphoto(照片修复),aruco(二维码和AR标记识别),face(人脸...
# OpenCV-MinGW-Build MinGW version of OpenCV compiled on Windows. ## [OpenCV 3.4.1](https://github.com/huihut/OpenCV-MinGW-Build/tree/OpenCV-3.4.1) ``` git clone -b OpenCV-3.4.1 git@github....
Python版本的OpenCV库,也就是`opencv-python`,为Python程序员提供了方便的接口来利用这个功能丰富的库。在本案例中,我们讨论的是OpenCV的Python接口的4.10.0.84版本,它是一个经过编译的二进制包,文件名为`...
1. **集成OpenCV到Android项目**:首先,开发者需要将下载的opencv-4.5.0-android-sdk.zip或opencv-4.4.0-android-sdk.zip解压,获取到对应的AAR库文件。然后,通过Android Studio的Gradle构建系统,将AAR库添加到...
这个"opencv-4.9.0-android"版本是OpenCV针对Android平台的特定优化版本,包含了最新的特性和性能改进。 1. **OpenCV库的核心功能**: - 图像处理:包括滤波、边缘检测(如Canny、Sobel、Laplacian)、色彩转换...
OpenCV-4.1.0-android-sdk包含了以下关键组件: 1. **库文件**:包含了OpenCV库的预编译版本,包括动态库(.so文件)和头文件,供开发者在Android Studio项目中链接使用。 2. **Java API**:提供了一套完整的Java...
这个压缩包"opencv-4.6.0-vc14-vc15.exe"很可能是OpenCV的特定版本,兼容Visual Studio 2014 (VC14) 和 Visual Studio 2015 (VC15) 的编译环境。 OpenCV 4.6.0是该库的一个稳定版本,可能包含了自4.0.0版本以来的...
首先,我们关注的是"opencv-4.8.0-windows.exe",这是一个针对Windows平台的OpenCV安装包。OpenCV在Windows上提供了丰富的API和函数,支持C++、Python、Java等多种编程语言,便于开发者进行图像处理和计算机视觉项目...