您的位置:首页 > 其它

图像轮廓检测,创建Trackbar & 图像对比度、亮度值调整

2015-04-17 14:44 441 查看
今天学习到@浅墨_毛星云博主的关于OpenCV的第六篇博文,详细的讲解了创建Trackbar & 图像对比度、亮度值调整 ,也给出了具体的实例,再此我将自学的记录做一个总计与汇总,欢迎各位朋友一起学习,若有不妥之处,欢迎指正。

相关链接@浅墨_毛星云:/article/1381163.html

大步朝前:http://blog.csdn.net/qq61394323/article/details/9830027
http://blog.csdn.net/fulva/article/details/7535760
------------------------------------------------------------------------------
static void on_trackbar(int, void*)
{
/*
如果threshval小于128,则当img中相应元素小于threshval时,bw赋255,大于threshval时赋0。
如果threshval大于128,则当img相应元素大于threshval时,bw赋255,小于threshval时赋0
*/
Mat bw = threshval < 128 ? (img < threshval) : (img > threshval);

namedWindow("bw", 1);//可以查看效果。threshval < 128的图像相当于为threshval >128的取反
imshow("bw", bw);
//定义点和向量
/*
vector是容器 可以理解成一个可变长的数组 第一句生成一个point型的二维数组变量contours(每一维长度均可变)
第二句是生成一个Vec4i型的一维数组hierarchy  <>里面写的是容器的数据类型
*/
vector<vector<Point> > contours;//存放轮廓,但是每个vector<Point>元素不一定只表示一个轮廓。
vector<Vec4i> hierarchy;//存放轮廓之间的拓扑关系。hierarchy[idx][0]、 hierarchy[idx][1]、 hierarchy[idx][2]、 hierarchy[idx][3]分别表示索引为idx的轮廓的前一个、后一个、子、父轮廓对应的索引;当索引为0时,表示相应的轮廓不存在。

//查找轮廓
findContours( bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
//初始化dst
Mat dst = Mat::zeros(img.size(), CV_8UC3);//定义一容易并初始化
//开始处理
if( !contours.empty() && !hierarchy.empty() )
{
//遍历所有顶层轮廓,随机生成颜色值绘制给各连接组成部分
int idx = 0;
for( ; idx >= 0; idx = hierarchy[idx][0] )
{
Scalar color( (rand()&255), (rand()%255), (rand()%255) );//(rand()&255)的含义为将随机产生的随机数范围现定于0-255之间,相当于rand()%255
//绘制填充轮廓
drawContours( dst, contours, idx, color, CV_FILLED, 8, hierarchy );
}
}
//显示窗口
imshow( "Connected Components", dst );
}

//-----------------------------------【main( )函数】--------------------------------------------
//	描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main(  )
{
system("color 4F");
//载入图片
img=imread("1.jpg", 0);
if( !img.data ) { printf("Oh,no,读取img图片文件错误~! \n"); return -1; }

//显示原图
namedWindow( "Image", 1 );
imshow( "Image", img );

//创建处理窗口
namedWindow( "Connected Components", 1 );
//创建轨迹条
createTrackbar( "Threshold", "Connected Components", &threshval, 255, on_trackbar );
on_trackbar(threshval, 0);//轨迹条回调函数

waitKey(0);
return 0;
}


cv2.findContours()函数

函数的原型为

CV_EXPORTS_W void findContours( InputOutputArray image, OutputArrayOfArrays contours,
OutputArray hierarchy, int mode,
int method, Point offset=Point());


这里介绍下该函数的各个参数:
输入图像image必须为一个2值单通道图像

contours参数为检测的轮廓数组,每一个轮廓用一个point类型的vector表示

hiararchy参数和轮廓个数相同,每个轮廓contours[ i ]对应4个hierarchy元素hierarchy[ i ][ 0 ] ~hierarchy[ i ][ 3 ],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,该值设置为负数。

mode表示轮廓的检索模式

CV_RETR_EXTERNAL表示只检测外轮廓

CV_RETR_LIST检测的轮廓不建立等级关系

CV_RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。

CV_RETR_TREE建立一个等级树结构的轮廓。具体参考contours.c这个demo

method为轮廓的近似办法

CV_CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1

CV_CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息

CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法

offset表示代表轮廓点的偏移量,可以设置为任意值。对ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数还是很有用的。

具体应用参考sample文件夹下面的squares.cpp这个demo

findContours后会对输入的2值图像改变,所以如果不想改变该2值图像,需创建新mat来存放,findContours后的轮廓信息contours可能过于复杂不平滑,可以用approxPolyDP函数对该多边形曲线做适当近似

contourArea函数可以得到当前轮廓包含区域的大小,方便轮廓的筛选

findContours经常与drawContours配合使用,用来将轮廓绘制出来。其中第一个参数image表示目标图像,第二个参数contours表示输入的轮廓组,每一组轮廓由点vector构成,第三个参数contourIdx指明画第几个轮廓,如果该参数为负值,则画全部轮廓,第四个参数color为轮廓的颜色,第五个参数thickness为轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内部,第六个参数lineType为线型,第七个参数为轮廓结构信息,第八个参数为maxLevel

得到了复杂轮廓往往不适合特征的检测,这里再介绍一个点集凸包络的提取函数convexHull,输入参数就可以是contours组中的一个轮廓,返回外凸包络的点集

还可以得到轮廓的外包络矩形,使用函数boundingRect,如果想得到旋转的外包络矩形,使用函数minAreaRect,返回值为RotatedRect;也可以得到轮廓的外包络圆,对应的函数为minEnclosingCircle;想得到轮廓的外包络椭圆,对应的函数为fitEllipse,返回值也是RotatedRect,可以用ellipse函数画出对应的椭圆

如果想根据多边形的轮廓信息得到多边形的多阶矩,可以使用类moments,这个类可以得到多边形和光栅形状的3阶以内的所有矩,类内有变量m00,m10,m01,m20,m11,m02,m30,m21,m12,m03,比如多边形的质心为 x = m10 / m00,y = m01 / m00。

如果想获得一点与多边形封闭轮廓的信息,可以调用pointPolygonTest函数,这个函数返回值为该点距离轮廓最近边界的距离,为正值为在轮廓内部,负值为在轮廓外部,0表示在边界上。

DrawContours

在图像中绘制外部和内部的轮廓。

void cvDrawContours( CvArr *img, CvSeq* contour,
CvScalar external_color, CvScalar hole_color,
int max_level, int thickness=1,
int line_type=8, CvPoint offset=cvPoint(0,0) );

img用以绘制轮廓的图像。和其他绘图函数一样,边界图像被感兴趣区域(ROI)所剪切。contour指针指向第一个轮廓。external_color外层轮廓的颜色。 hole_color内层轮廓的颜色。 max_level
绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。

thickness绘制轮廓时所使用的线条的粗细度。如果值为负(e.g. =CV_FILLED),绘制内层轮廓。line_type线条的类型。参考cvLine.offset按照给出的偏移量移动每一个轮廓点坐标.当轮廓是从某些感兴趣区域(ROI)中提取的然后需要在运算中考虑ROI偏移量时,将会用到这个参数。
当thickness>=0,函数cvDrawContours在图像中绘制轮廓,或者当thickness<0时,填充轮廓所限制的区域。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐