参考了许多博客,自己整理了一下几种方法用来提取图像轮廓的方法,记录一下
#include
#include
#include
#include
using namespace cv;
using namespace std;
//方法1
void Contours1(Mat &image)
{
//将image由彩色图像转换成灰度图像
cvtColor(image,image,CV_BGR2GRAY);
//再通过阈值函数将其转换为二值图像
threshold(image,image,160,255,THRESH_BINARY);//设置阈值为160,最大像素值为255
vector> contours;
//find轮廓
findContours(image,contours,1,CHAIN_APPROX_SIMPLE);
//draw轮廓
Mat result=Mat::zeros(image.size(),CV_8UC1);
if(!contours.empty())
{
//result:存放轮廓,contours:找到的轮廓,-1:将所有轮廓画出,Scalar(255):由白色画,2:画笔粗细
drawContours(result,contours,-1,Scalar(255),2);
imshow("处理图",result);
}
}
//方法2
void Contours2(Mat &image)
{
Mat img1=Mat::zeros(image.size(),CV_8UC1);
//将image由彩色图像转换成灰度图像
cvtColor(image,image,CV_RGB2GRAY);
//通过阈值函数将其转换为二值图像img1(大小与image一样,是单通道)
threshold(image,img1,160,255,THRESH_BINARY);//设置阈值为160,最大像素值为255
vector >contours;//contours轮廓
vector hierarchy;//hierarchy层次
//查找轮廓findContours
findContours(img1,contours,hierarchy,CV_RETR_CCOMP,CHAIN_APPROX_SIMPLE);
//初始化dst
Mat dst=Mat::zeros(image.size(),CV_8UC1);
//开始处理
if(!contours.empty()&&!hierarchy.empty())
{ //循环轮廓数
for (int i = 0; i < contours.size(); i++)
{
//循环当前轮廓下的每一个点,contours[i].size()是当前轮廓下的总点数
for (int j = 0; j < contours[i].size(); j++)
{
Point p=Point(contours[i][j].x,contours[i][j].y);
//给当前轮廓下的每个点设置白色
dst.at(p)=255;
}
//drawContours绘制填充当前的轮廓i
drawContours(img,contours,i,Scalar(255),1,8,hierarchy);
}
}
imshow("处理图",dst);
}
//方法3
void Contours3(Mat &image)
{
Mat img;
GaussianBlur(image,img,Size(3,3),0);
Canny(img,img,100,250);
//定义点和向量
vector >contours;//contours轮廓
vector hierarchy;//hierarchy层次
//查找轮廓findContours
//参数1:为二值图像,可以是灰度图像,一般是经过Canny,拉普拉斯等边缘检测算子处理过的二值图像
//参数2:contours是一个双向的向量,向量内每个元素保存了一组由连续Point点构成的点集合向量,
//-------每一组点集就是一个轮廓,有多少轮廓contours就有多少元素
//参数3:hierarchy向量中每一个元素包含了4个int变量:hierarchy[i][0]~hierarchy[i][3]分别表示第i个轮廓的后一个,前一个,父,内嵌轮廓
//-------hierarchy向量内的元素和contours轮廓向量内的元素是一一对应的,向量的容量相同。
//参数4:定义轮廓的检索模式
//参数5:定义轮廓的近似方法
//参数6:Point偏移量,所有轮廓信息相对于原始图像对应点的偏移量
findContours(img,contours,hierarchy,CV_RETR_CCOMP,CHAIN_APPROX_SIMPLE);
//初始化dst
Mat dst=Mat::zeros(img.size(),CV_8UC1);
//开始处理
if(!contours.empty()&&!hierarchy.empty())
{
for (int i = 0; i < contours.size(); i++)
{
for (int j = 0; j < contours[i].size(); j++)
{
Point p=Point(contours[i][j].x,contours[i][j].y);
dst.at(p)=255;
}
//绘制填充轮廓
drawContours(img,contours,i,Scalar(255),1,8,hierarchy);
}
}
imshow("处理图",dst);
}
//方法4
void Contours4(Mat &img)
{
//将image由彩色图像转换成灰度图像
cvtColor(img,img,CV_RGB2GRAY);
//通过阈值转换成二值图像
Mat bw=(threshval<128)?(imgthreshval);
vector> contours;
//find轮廓
findContours(bw,contours,1,CHAIN_APPROX_SIMPLE);
//draw轮廓
Mat result=Mat::zeros(img.size(),CV_8UC1);
if(!contours.empty())
{
//result:存放轮廓,contours:找到的轮廓,-1:将所有轮廓画出,Scalar(255):由白色画,2:画笔粗细
drawContours(result,contours,-1,Scalar(255),2);
imshow("处理图",result);
}
}
int main()
{
img=imread("img/logo.png",1);
namedWindow("1");
imshow("1",img);
//创建处理窗口
namedWindow("处理图");
Contours1(img);//方法1
Contours2(img);//方法2
Contours3(img);//方法3
Contours4(img);//方法4
waitKey();
return 0;
}