刚学OpenCV,并且不懂VC++,费了几天的气力在网上终于找到了findContours查找轮廓后,怎么获得轮廓数,轮廓内包含点数,以及每个点坐标值的方法,为了方便自己以后查阅,同时也为了像我一样的“门外汉”们节省点时间,把源代码晒一下,见笑了。 主体源代码取自浅墨老师的书《OpenCV3编程入门》OpenC3版书本配套示例程序70,在此,向浅墨老师表示敬意和感谢!还有几行代码取自于网络,网址也做了标注,在此,一并向文章博主、楼主表示感谢!
main.cpp
//---------------------------------【头文件、命名空间包含部分】----------------------------
// 描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include"opencv2/highgui/highgui.hpp"
#include"opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
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("color1F");
//【0】显示欢迎和帮助文字
ShowHelpText();
//加载源图像
g_srcImage= imread("..\\hlw.jpg", 1);
if(!g_srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n");return false; }
/*//对图像四周边7像素内的区域全部灰度化
for(int row = 0; row < g_srcImage.rows; row++) {
for(int col = 0; col < g_srcImage.cols; col++) {
if(row < 8 || row>(g_srcImage.rows-8)) {
g_srcImage.at<Vec3b>(row,col)[0] = 127;
g_srcImage.at<Vec3b>(row,col)[1] = 127;
g_srcImage.at<Vec3b>(row,col)[2] = 127;
}
if((row > 8 || row < (g_srcImage.rows-8))&& (col < 8 || col >(g_srcImage.cols - 8))) {
g_srcImage.at<Vec3b>(row,col)[0] = 127;
g_srcImage.at<Vec3b>(row,col)[1] = 127;
g_srcImage.at<Vec3b>(row,col)[2] = 127;
}
}
}
imwrite("..\\hlwC.jpg",g_srcImage);*/ //查看切边效果
//转成灰度并模糊化降噪
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_LIST, CHAIN_APPROX_NONE, Point(0, 0));
cout<< "轮廓的总个数是 " << g_vContours.size() << endl;
/*// 下面四行来自http://www.cnblogs.com/wsc36305/archive/2012/10/15/2725218.html
vector<vector<Point>>::const_iteratoritContours = g_vContours.begin();
for(; itContours != g_vContours.end(); ++itContours) {
cout<< "Size: " << itContours->size() << endl;//每个轮廓包含的点数
}*/
//绘出轮廓
Matdrawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
for(int i = 0; i< g_vContours.size(); i++)
{
Scalarcolor = Scalar/*(255, 255, 255);// */ (g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0, 255));//任意值
drawContours(drawing,g_vContours, i, color, 1, 8, g_vHierarchy, 0, Point());
printf("\n输出 轮廓序号,第 个轮廓: %d \n", i);
//下面一行来自 http://blog.csdn.net/dcrmg/article/details/51987348
cout<< "输出轮廓包含点的总数: " <<g_vContours[i].size() << endl; //试试看输出该轮廓点的总数
// 下面三行来自http://www.opencv.org.cn/forum.php?mod=viewthread&tid=38297&page=4
cout<< "输出轮廓第0个点的坐标 " <<g_vContours[i][0] << endl; //试试看输出轮廓第一个点的坐标 x,y
//cout<< "输出轮廓第0个点的x坐标 " <<g_vContours[i][0].x << endl; //试试看输出轮廓第一个点的横坐标 x
//cout<< "输出轮廓第0个点的y坐标 " <<g_vContours[i][0].y << endl; //试试看输出轮廓第一个点的纵坐标 y
}
//显示效果图
imwrite("..\\findContours.bmp",drawing);
imshow(WINDOW_NAME2,drawing);
}
//-----------------------------------【ShowHelpText()函数】----------------------------------
// 描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
static void ShowHelpText()
{
//输出欢迎信息和OpenCV版本
printf("\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n");
printf("\n\n\t\t\t此为本书OpenCV3版的第70个配套示例程序\n");
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");
}


