opencv 6 图像轮廓与图像分割修复 1 查找并绘制轮廓 寻找物体的凸包
查找并绘制轮廓
寻找轮廓(findContours)函数
绘制轮廓(drawContours()函数)
基础实例程序:轮廓查找
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(int argc, char** argv)
{
// 【1】载入原始图,且必须以二值图模式载入
Mat srcImage = imread("1.jpg", 0);
imshow("原始图", srcImage);
//【2】初始化结果图
Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);
//【3】srcImage取大于阈值119的那部分
srcImage = srcImage > 119;
imshow("取阈值后的原始图", srcImage);
//【4】定义轮廓和层次结构
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
//【5】查找轮廓
//此句代码的OpenCV3版为:
findContours(srcImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
// 【6】遍历所有顶层的轮廓, 以随机颜色绘制出每个连接组件颜色
int index = 0;
for (; index >= 0; index = hierarchy[index][0])
{
Scalar color(rand() & 255, rand() & 255, rand() & 255);
drawContours(dstImage, contours, index, color, FILLED, 8, hierarchy);
}
//【7】显示最后的轮廓图
imshow("轮廓图", dstImage);
waitKey(0);
}
综合实例程序(加blur,canny和滑动条):
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
//-----------------------------------【宏定义部分】--------------------------------------------
// 描述:定义一些辅助宏
//------------------------------------------------------------------------------------------------
#define WINDOW_NAME1 "【原始图窗口】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【轮廓图】" //为窗口标题定义的宏
//-----------------------------------【全局变量声明部分】--------------------------------------
// 描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage;
Mat g_grayImage;
int g_nThresh = 80;
int g_nThresh_max = 255;
RNG g_rng(12345);
Mat g_cannyMat_output;
vector<vector<Point>> g_vContours;
vector<Vec4i> g_vHierarchy;
//-----------------------------------【全局函数声明部分】--------------------------------------
// 描述:全局函数的声明
//-----------------------------------------------------------------------------------------------
static void ShowHelpText();
void on_ThreshChange(int, void*);
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main(int argc, char** argv)
{
//【0】改变console字体颜色
system("color 1F");
//【0】显示欢迎和帮助文字
ShowHelpText();
// 加载源图像
g_srcImage = imread("1.jpg", 1);
if (!g_srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
// 转成灰度并模糊化降噪
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
blur(g_grayImage, g_grayImage, Size(3, 3));
// 创建窗口
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME1, g_srcImage);
//创建滚动条并初始化
createTrackbar("canny阈值", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange);
on_ThreshChange(0, 0);
waitKey(0);
return(0);
}
//-----------------------------------【on_ThreshChange( )函数】------------------------------
// 描述:回调函数
//----------------------------------------------------------------------------------------------
void on_ThreshChange(int, void*)
{
// 用Canny算子检测边缘
Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);
// 寻找轮廓
findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
// 绘出轮廓
Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
for (int i = 0; i < g_vContours.size(); i++)
{
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值
drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());
}
// 显示效果图
imshow(WINDOW_NAME2, drawing);
}
//-----------------------------------【ShowHelpText( )函数】----------------------------------
// 描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
static void ShowHelpText()
{
//输出欢迎信息和OpenCV版本
printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION);
printf("\n\n ----------------------------------------------------------------------------\n");
//输出一些帮助信息
printf("\n\n\t欢迎来到【在图形中寻找轮廓】示例程序~\n\n");
printf("\n\n\t按键操作说明: \n\n"
"\t\t键盘按键任意键- 退出程序\n\n"
"\t\t滑动滚动条-改变阈值\n");
}
寻找物体的凸包
寻找凸包(convexHull()函数)
基础示例程序:凸包检测基础
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
//-----------------------------------【ShowHelpText( )函数】----------------------------------
// 描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
static void ShowHelpText()
{
//输出欢迎信息和OpenCV版本
printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION);
printf("\n\n ----------------------------------------------------------------------------\n");
//输出一些帮助信息
printf("\n\t欢迎来到【凸包检测】示例程序~\n\n");
printf("\n\t按键操作说明: \n\n"
"\t\t键盘按键【ESC】、【Q】、【q】- 退出程序\n\n"
"\t\t键盘按键任意键 - 重新生成随机点,并进行凸包检测\n");
}
//--------------------------------------【main( )函数】-----------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main()
{
//改变console字体颜色
system("color 1F");
//显示帮助文字
ShowHelpText();
//初始化变量和随机值
Mat image(600, 600, CV_8UC3);
RNG& rng = theRNG();
//循环,按下ESC,Q,q键程序退出,否则有键按下便一直更新
while (1)
{
//参数初始化
char key;//键值
int count = (unsigned)rng % 100 + 3;//随机生成点的数量
vector<Point> points; //点值
//随机生成点坐标
for (int i = 0; i < count; i++)
{
Point point;
point.x = rng.uniform(image.cols / 4, image.cols * 3 / 4);
point.y = rng.uniform(image.rows / 4, image.rows * 3 / 4);
points.push_back(point);
}
//检测凸包
vector<int> hull;
convexHull(Mat(points), hull, true);
//绘制出随机颜色的点
image = Scalar::all(0);
for (int i = 0; i < count; i++)
circle(image, points[i], 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), FILLED, LINE_AA);
//准备参数
int hullcount = (int)hull.size();//凸包的边数
Point point0 = points[hull[hullcount - 1]];//连接凸包边的坐标点
//绘制凸包的边
for (int i = 0; i < hullcount; i++)
{
Point point = points[hull[i]];
line(image, point0, point, Scalar(255, 255, 255), 2, LINE_AA);
point0 = point;
}
//显示效果图
imshow("凸包检测示例", image);
//按下ESC,Q,或者q,程序退出
key = (char)waitKey();
if (key == 27 || key == 'q' || key == 'Q')
break;
}
return 0;
}
综合实例程序:寻找和绘制物体的凸包
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
//-----------------------------------【宏定义部分】--------------------------------------------
// 描述:定义一些辅助宏
//------------------------------------------------------------------------------------------------
#define WINDOW_NAME1 "【原始图窗口】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【效果图窗口】" //为窗口标题定义的宏
//-----------------------------------【全局变量声明部分】--------------------------------------
// 描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage; Mat g_grayImage;
int g_nThresh = 50;
int g_maxThresh = 255;
RNG g_rng(12345);
Mat srcImage_copy = g_srcImage.clone();
Mat g_thresholdImage_output;
vector<vector<Point> > g_vContours;
vector<Vec4i> g_vHierarchy;
//-----------------------------------【全局函数声明部分】--------------------------------------
// 描述:全局函数的声明
//-----------------------------------------------------------------------------------------------
void on_ThreshChange(int, void*);
//-----------------------------------【main( )函数】------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main()
{
// 加载源图像
g_srcImage = imread("1.jpg", 1);
// 将原图转换成灰度图并进行模糊降
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
blur(g_grayImage, g_grayImage, Size(3, 3));
// 创建原图窗口并显示
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME1, g_srcImage);
//创建滚动条
createTrackbar(" 阈值:", WINDOW_NAME1, &g_nThresh, g_maxThresh, on_ThreshChange);
on_ThreshChange(0, 0);//调用一次进行初始化
waitKey(0);
return(0);
}
//-----------------------------------【thresh_callback( )函数】----------------------------------
// 描述:回调函数
//----------------------------------------------------------------------------------------------
void on_ThreshChange(int, void*)
{
// 对图像进行二值化,控制阈值
threshold(g_grayImage, g_thresholdImage_output, g_nThresh, 255, THRESH_BINARY);
// 寻找轮廓
findContours(g_thresholdImage_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
// 遍历每个轮廓,寻找其凸包
vector<vector<Point> >hull(g_vContours.size());
for (unsigned int i = 0; i < g_vContours.size(); i++)
{
convexHull(Mat(g_vContours[i]), hull[i], false);
}
// 绘出轮廓及其凸包
Mat drawing = Mat::zeros(g_thresholdImage_output.size(), CV_8UC3);
for (unsigned int i = 0; i < g_vContours.size(); i++)
{
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));
drawContours(drawing, g_vContours, i, color, 1, 8, vector<Vec4i>(), 0, Point());
drawContours(drawing, hull, i, color, 1, 8, vector<Vec4i>(), 0, Point());
}
// 显示效果图
imshow(WINDOW_NAME2, drawing);
}
HSV学习链接https://blog.csdn.net/coldwindha/article/details/82080176
opencv 6 图像轮廓与图像分割修复 1 查找并绘制轮廓 寻找物体的凸包的更多相关文章
- opencv 6 图像轮廓与图像分割修复 2 使用多边形将轮廓包围
使用多边形将轮廓包围 返回外部矩阵边界(boundingRect()函数) 寻找最小包围矩形(minAreaRect()函数) 寻找最小包围圆形(minEnclosingCircle函数) 用椭圆拟合 ...
- opencv 6 图像轮廓与图像分割修复 3 图像的矩,分水岭,图像修补
图像的矩 矩的计算:moments()函数 计算轮廓面积:contourArea()函数 #include "opencv2/highgui/highgui.hpp" #inclu ...
- 查找并绘制轮廓[OpenCV 笔记XX]
好久没有更新了,原谅自己放了个假最近又在赶进度,所以...更新的内容是很靠后的第八章,因为最近工作要用就先跳了,后面会更新笔记编号...加油加油! 在二值图像中寻找轮廓 void cv::findCo ...
- 查找并绘制轮廓 opencv
findContours(): 第二个参数为一个检测到的轮廓,函数调用后的运算结果都放在这里,每个轮廓存储为1个点向量,用point类型的vector表示. 第三个参数表示轮廓数量,包含了许多元素.每 ...
- OpenCV——查找、绘制轮廓
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...
- 寻找物体的凸包 opencv
凸包的含义: 在二维平面上给定点集,凸包就是将最外层的点连接起来构成的凸多边形.并且这个凸多边形能包含点集中所有的点.OPENCV中: convexHull函数用于寻找图像点集中的凸包.它有六个输入参 ...
- opencv学习之路(23)、轮廓查找与绘制(二)——访问轮廓每个点
一.简介 二.画出每个轮廓的每个点 #include "opencv2/opencv.hpp" using namespace cv; void main() { Mat src= ...
- Opencv分水岭算法——watershed自动图像分割用法
分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特 ...
- 图像分割之(五)活动轮廓模型之Snake模型简介
在"图像分割之(一)概述"中咱们简单了解了目前主流的图像分割方法.下面咱们主要学习下基于能量泛函的分割方法.这里学习下Snake模型简单的知识,Level Set(水平集)模型会在 ...
随机推荐
- selenium-模块概述(1)
Selenium是一个用于Web应用程序自动化测试工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样. 1.目录结构如下: D:\soft\python36\Lib\site-pa ...
- VMware安装和linux(centos7)系统安装
下载centos系统ISO镜像 安装linux系统和winsdows安装系统一样,需要系统文件.浏览器访问centos官网进行下载,http://www.centos.org,因为是国外网站所有下载速 ...
- Js极客之路 - 简化操作
1.对字符串使用单引号(避免动态添加元素时html会出现的双引号"引起的冲突,方便操作 - 单引号一个键,双引号两个键) // bad var name = "Barrior&qu ...
- PowerBI开发 第十五篇:Power BI的行级安全
Power BI支持行级安全(Row-Level Security,RLS)的权限控制,用于限制用户对Dashboard.报表和DataSet的访问.用户浏览的报表是相同的,但是看到的数据却是不同的. ...
- TwoHandleSlider/RangeSlider
项目需求:双滑块slider,可以实现选择一个范围 (一)添加两个slider,并把背景以及fill设置为透明,并去除RaycastTarget (二)在背景下添加个一个image,背景图为滑块划过后 ...
- SpringBoot配置文件之Yml语法
一 使用 YAML 而不是 Properties YAML是 JSON 的超集,因此,它是用于指定分层配置数据的便捷格式.只要 class 路径上有SnakeYAML library,SpringAp ...
- 《大数据实时计算引擎 Flink 实战与性能优化》新专栏
基于 Flink 1.9 讲解的专栏,涉及入门.概念.原理.实战.性能调优.系统案例的讲解. 专栏介绍 扫码下面专栏二维码可以订阅该专栏 首发地址:http://www.54tianzhisheng. ...
- FTP上传、下载文件Demo
前言:最近在做一个app,负责写后台接口,客户那边给了一个FTP的账号密码过来,服务器上面放了一堆的PDF文件,让我们这边自己从上面拿,项目是spriongboot的,做个记录供以后参考. 一.app ...
- 12 Zabbix4.4.0系统sendEmail邮件报警优化
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 12 Zabbix4.4.0系统sendEmail邮件报警优化 接上一章节 Zabbix4.4. ...
- .NET进阶篇06-async异步、thread多线程1
知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂 异步多线程挺大一块内容,既想拆开慢慢学,又想一股脑全倒出.纠结再三,还是拆开吃透,也不至于篇幅过长,劝退许多人 本篇先做一个概述,列明一些基本概 ...