opencv 6 图像轮廓与图像分割修复 2 使用多边形将轮廓包围
使用多边形将轮廓包围
返回外部矩阵边界(boundingRect()函数)
寻找最小包围矩形(minAreaRect()函数)
寻找最小包围圆形(minEnclosingCircle函数)
用椭圆拟合二维点集(fitEllipse()函数)
逼近多边形曲线(approxPolyDP()函数)
基础示例:创建包围轮廓的矩形边界
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
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\n\n\t\t\t欢迎来到【矩形包围示例】示例程序~\n\n");
printf("\n\n\t按键操作说明: \n\n"
"\t\t键盘按键【ESC】、【Q】、【q】- 退出程序\n\n"
"\t\t键盘按键任意键 - 重新生成随机点,并寻找最小面积的包围矩形\n");
}
int main()
{
//改变console字体颜色
system("color 1F");
//显示帮助文字
ShowHelpText();
//初始化变量和随机值
Mat image(600, 600, CV_8UC3);
RNG& rng = theRNG();
//循环,按下ESC,Q,q键程序退出,否则有键按下便一直更新
while (1)
{
//参数初始化
int count = rng.uniform(3, 103);//随机生成点的数量
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);
}
//对给定的 2D 点集,寻找最小面积的包围矩形
RotatedRect box = minAreaRect(Mat(points));
Point2f vertex[4];
box.points(vertex);
//绘制出随机颜色的点
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);
//绘制出最小面积的包围矩形
for (int i = 0; i < 4; i++)
line(image, vertex[i], vertex[(i + 1) % 4], Scalar(100, 200, 211), 2, LINE_AA);
//显示窗口
imshow("矩形包围示例", image);
//按下ESC,Q,或者q,程序退出
char key = (char)waitKey();
if (key == 27 || key == 'q' || key == 'Q') // 'ESC'
break;
}
return 0;
}
基础示例:创建包围轮廓的圆形边界、
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
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\n\t\t\t欢迎来到【寻找最小面积的包围圆】示例程序~\n");
printf("\n\n\t按键操作说明: \n\n"
"\t\t键盘按键【ESC】、【Q】、【q】- 退出程序\n\n"
"\t\t键盘按键任意键 - 重新生成随机点,并寻找最小面积的包围圆\n" );
}
int main( )
{
//改变console字体颜色
system("color 1F");
//显示帮助文字
ShowHelpText();
//初始化变量和随机值
Mat image(600, 600, CV_8UC3);
RNG& rng = theRNG();
//循环,按下ESC,Q,q键程序退出,否则有键按下便一直更新
while(1)
{
//参数初始化
int count = rng.uniform(3, 103);//随机生成点的数量
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);
}
//对给定的 2D 点集,寻找最小面积的包围圆
Point2f center;
float radius = 0;
minEnclosingCircle(Mat(points), center, radius);
//绘制出随机颜色的点
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 );
//绘制出最小面积的包围圆
circle(image, center, cvRound(radius), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);//cvRound四舍五入
//显示窗口
imshow( "圆形包围示例", image );
//按下ESC,Q,或者q,程序退出
char key = (char)waitKey();
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
break;
}
return 0;
}
综合示例程序:使用多边形包围轮廓
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
//-----------------------------------【宏定义部分】--------------------------------------------
// 描述:定义一些辅助宏
//------------------------------------------------------------------------------------------------
#define WINDOW_NAME1 "【原始图窗口】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【效果图窗口】" //为窗口标题定义的宏
//-----------------------------------【全局变量声明部分】--------------------------------------
// 描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage;
Mat g_grayImage;
int g_nThresh = 50;//阈值
int g_nMaxThresh = 255;//阈值最大值
RNG g_rng(12345);//随机数生成器
//-----------------------------------【全局函数声明部分】--------------------------------------
// 描述:全局函数的声明
//-----------------------------------------------------------------------------------------------
void on_ContoursChange(int, void*);
static void ShowHelpText();
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main()
{
//【0】改变console字体颜色
system("color 1F");
//【0】显示欢迎和帮助文字
ShowHelpText();
//【1】载入3通道的原图像
g_srcImage = imread("1.jpg", 1);
if (!g_srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
//【2】得到原图的灰度图像并进行平滑
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
blur(g_grayImage, g_grayImage, Size(3, 3));
//【3】创建原始图窗口并显示
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME1, g_srcImage);
//【4】设置滚动条并调用一次回调函数
createTrackbar(" 阈值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ContoursChange);
on_ContoursChange(0, 0);
waitKey(0);
return(0);
}
//----------------------------【on_ContoursChange( )函数】---------------------------------
// 描述:回调函数
//-------------------------------------------------------------------------------------------------
void on_ContoursChange(int, void*)
{
//定义一些参数
Mat threshold_output;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
// 使用Threshold检测边缘
threshold(g_grayImage, threshold_output, g_nThresh, 255, THRESH_BINARY);
// 找出轮廓
findContours(threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
// 多边形逼近轮廓 + 获取矩形和圆形边界框
vector<vector<Point> > contours_poly(contours.size());
vector<Rect> boundRect(contours.size());
vector<Point2f>center(contours.size());
vector<float>radius(contours.size());
//一个循环,遍历所有部分,进行本程序最核心的操作
for (unsigned int i = 0; i < contours.size(); i++)
{
approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);//用指定精度逼近多边形曲线
boundRect[i] = boundingRect(Mat(contours_poly[i]));//计算点集的最外面(up-right)矩形边界
minEnclosingCircle(contours_poly[i], center[i], radius[i]);//对给定的 2D点集,寻找最小面积的包围圆形
}
// 绘制多边形轮廓 + 包围的矩形框 + 圆形框
Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
for (int unsigned i = 0; i < contours.size(); i++)
{
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//随机设置颜色
drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point());//绘制轮廓
rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);//绘制矩形
circle(drawing, center[i], (int)radius[i], color, 2, 8, 0);//绘制圆
}
// 显示效果图窗口
namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
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\n\t欢迎来到【创建包围轮廓的矩形和圆形边界框】示例程序~\n\n");
printf("\n\n\t按键操作说明: \n\n"
"\t\t键盘按键【ESC】- 退出程序\n\n"
"\t\t滑动滚动条 - 改变阈值\n\n");
}
opencv 6 图像轮廓与图像分割修复 2 使用多边形将轮廓包围的更多相关文章
- opencv 6 图像轮廓与图像分割修复 1 查找并绘制轮廓 寻找物体的凸包
查找并绘制轮廓 寻找轮廓(findContours)函数 绘制轮廓(drawContours()函数) 基础实例程序:轮廓查找 #include <opencv2/opencv.hpp> ...
- opencv 6 图像轮廓与图像分割修复 3 图像的矩,分水岭,图像修补
图像的矩 矩的计算:moments()函数 计算轮廓面积:contourArea()函数 #include "opencv2/highgui/highgui.hpp" #inclu ...
- Opencv分水岭算法——watershed自动图像分割用法
分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特 ...
- 图像分割之(五)活动轮廓模型之Snake模型简介
在"图像分割之(一)概述"中咱们简单了解了目前主流的图像分割方法.下面咱们主要学习下基于能量泛函的分割方法.这里学习下Snake模型简单的知识,Level Set(水平集)模型会在 ...
- (转)使用Python和OpenCV检测图像中的物体并将物体裁剪下来
原文链接:https://blog.csdn.net/liqiancao/article/details/55670749 介绍 硕士阶段的毕设是关于昆虫图像分类的,代码写到一半,上周五导师又给我新的 ...
- opencv —— inpaint 图像修补、去除指定区域物体
实现图像修补.物体去除:inpaint 函数 void inpaint(InputArray src, InputArray inpaintMask, OutputArray dst, double ...
- C#使用OpenCV剪切图像中的圆形和矩形
前言 本文主要介绍如何使用OpenCV剪切图像中的圆形和矩形. 准备工作 首先创建一个Wpf项目--WpfOpenCV,这里版本使用Framework4.7.2. 然后使用Nuget搜索[Emgu.C ...
- Java基于opencv实现图像数字识别(五)—投影法分割字符
Java基于opencv实现图像数字识别(五)-投影法分割字符 水平投影法 1.水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像): 2.选出一个最优的阀值,根据比这个阀值大或小 ...
- Java基于opencv实现图像数字识别(四)—图像降噪
Java基于opencv实现图像数字识别(四)-图像降噪 我们每一步的工作都是基于前一步的,我们先把我们前面的几个函数封装成一个工具类,以后我们所有的函数都基于这个工具类 这个工具类呢,就一个成员变量 ...
随机推荐
- C# Halcon联合编程问题(二)
避免重复编辑同一篇随笔,有问题就开一个新的,哪怕会很短. 还是之前那个问题,halcon中的HObject转换为Bitmap的问题,在全网找相关的办法,三通道图像的HObject转换为C#中的Bitm ...
- [Tarjan系列] Tarjan算法与有向图的SCC
前面的文章介绍了如何用Tarjan算法计算无向图中的e-DCC和v-DCC以及如何缩点. 本篇文章资料参考:李煜东<算法竞赛进阶指南> 这一篇我们讲如何用Tarjan算法求有向图的SCC( ...
- Ubuntu 14.04风扇不停转,风扇狂转 的解决办法,亲测有效。
Ubuntu 14.04风扇不停转,风扇狂转 的解决办法,亲测有效. 原文 http://ubuntuforums.org/showthread.php?t=2218367 楼主说:ubuntu 1 ...
- 设计模式(七)Builder模式
Builder模式,从这个名字我们可以看出来,这种设计模式就是用于组装具有复杂结构的实例的. 下面还是以一个实例程序来解释这种设计模式,先看实例程序的类图. 这里为了调试方便,只实现其中一个功能Tex ...
- unity www下载导致内存占用增加问题
服务端或者数据库更改导致客户端更改,最合理的处理方法是客户端时刻检测版本号(可以通过实时检测版本号),如果实时刷新数据库的数据开销比较大,尤其是有图片元素时. 采用unity www类下载时,虽然结束 ...
- AI Conference 2018人工智能大会 参会总结
主 题:AI Conference 2018人工智能大会 时 间:2018.04.11-4.13 地 点:北京国际饭店会议中心 发起人:O'Reilly 和 Intel 参与部门:研发设计部 参会人员 ...
- c#通过libreOffice实现 office文件转pdf文件
一.安装libreOffice 点击官网下载libreOffice 二.创建一个新的项目LibreOffice 创建一个新的项目,方便后面调用 添加下面代码 public class OfficeCo ...
- python:枚举类型
1.什么是枚举类型? 枚举类型可以看做是一系列常量的集合,通常用于表示某些有限且固定的集合,例如月份(一年有12个月).星期(一星期有七天).季节(一年四个季节)等. 2.枚举的定义 定义枚举首先要导 ...
- Netty 入门,这一篇文章就够了
Netty是Java领域有名的开源网络库,特点是高性能和高扩展性,因此很多流行的框架都是基于它来构建的,比如我们熟知的Dubbo.Rocketmq.Hadoop等,针对高性能RPC,一般都是基于Net ...
- 学习c++11 ThreadPool【转】
#ifndef THREAD_POOL_H #define THREAD_POOL_H #include <vector> #include <queue> #include ...