OpenCv学习笔记(六):使用opencv画线、矩形、椭圆、多边形线、多边形体等

合集下载

opencv 检测直线、线段、圆、矩形

opencv 检测直线、线段、圆、矩形

opencv检测直线、线段、圆、矩形检测直线:cvHoughLines,cvHoughLines2检测圆:cvHoughCircles检测矩形:opencv中没有对应的函数,下面有段代码可以检测矩形,是通过先找直线,然后找到直线平行与垂直的四根线。

检测直线代码:/* This is a standalone program. Pass an image name as a first parameter of the program.Switch between standard and probabilistic Hough transform by changing "#if 1" to "#if 0" and back */#include <cv.h>#include <highgui.h>#include <math.h>int main(intargc, char** argv){const char* filename = argc>= 2 ? argv[1] : "pic1.png";IplImage* src = cvLoadImage( filename, 0 );IplImage* dst;IplImage* color_dst;CvMemStorage* storage = cvCreateMemStorage(0);CvSeq* lines = 0;inti;if( !src )return -1;dst = cvCreateImage( cvGetSize(src), 8, 1 );color_dst = cvCreateImage(cvGetSize(src), 8, 3 );cvCanny(src, dst, 50, 200, 3 );cvCvtColor(dst, color_dst, CV_GRAY2BGR );#if 0lines = cvHoughLines2( dst, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 100, 0, 0 );for(i = 0; i< MIN(lines->total,100); i++ ){float* line = (float*)cvGetSeqElem(lines,i);float rho = line[0];float theta = line[1];CvPoint pt1, pt2;double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 1000*(-b));pt1.y = cvRound(y0 + 1000*(a));pt2.x = cvRound(x0 - 1000*(-b));pt2.y = cvRound(y0 - 1000*(a));cvLine(color_dst, pt1, pt2, CV_RGB(255,0,0), 3, CV_AA, 0 );}#elselines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 50, 50, 10 );for(i = 0; i< lines->total; i++ ){CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);cvLine(color_dst, line[0], line[1], CV_RGB(255,0,0), 3, CV_AA, 0 );}#endifcvNamedWindow( "Source", 1 );cvShowImage( "Source", src );cvNamedWindow( "Hough", 1 );cvShowImage( "Hough", color_dst );cvWaitKey(0);return 0;}检测圆代码:#include <cv.h>#include <highgui.h>#include <math.h>int main(intargc, char** argv){IplImage* img;if(argc == 2 && (img=cvLoadImage(argv[1], 1))!= 0){IplImage* gray = cvCreateImage(cvGetSize(img), 8, 1 );CvMemStorage* storage = cvCreateMemStorage(0);cvCvtColor(img, gray, CV_BGR2GRAY );cvSmooth( gray, gray, CV_GAUSSIAN, 9, 9 ); // smooth it, otherwise a lot of false circles may be detectedCvSeq* circles = cvHoughCircles( gray, storage, CV_HOUGH_GRADIENT, 2,gray->height/4, 200, 100 );inti;for(i = 0; i< circles->total; i++ ){float* p = (float*)cvGetSeqElem( circles, i );cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(0,255,0), -1, 8, 0 );cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 );}cvNamedWindow( "circles", 1 );cvShowImage( "circles", img ); }return 0;}检测矩形代码:/*在程序里找寻矩形*/#ifdef _CH_#pragma package <opencv> #endif#ifndef _EiC#include "cv.h"#include "highgui.h"#include <stdio.h>#include <math.h>#include <string.h>#endifint thresh = 50;IplImage* img = 0;IplImage* img0 = 0; CvMemStorage* storage = 0; CvPointpt[4];const char* wndname = "Square Detection Demo";// helper function:// finds a cosine of angle between vectors// from pt0->pt1 and from pt0->pt2double angle( CvPoint* pt1, CvPoint* pt2, CvPoint* pt0 ){double dx1 = pt1->x - pt0->x;double dy1 = pt1->y - pt0->y;double dx2 = pt2->x - pt0->x;double dy2 = pt2->y - pt0->y;return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); }// returns sequence of squares detected on the image.// the sequence is stored in the specified memory storageCvSeq* findSquares4(IplImage* img, CvMemStorage* storage ){CvSeq* contours;inti, c, l, N = 11;CvSizesz = cvSize(img->width & -2, img->height & -2 );IplImage* timg = cvCloneImage(img ); // make a copy of input imageIplImage* gray = cvCreateImage(sz, 8, 1 );IplImage* pyr = cvCreateImage(cvSize(sz.width/2, sz.height/2), 8, 3 ); IplImage* tgray;CvSeq* result;double s, t;// create empty sequence that will contain points -// 4 points per square (the square's vertices)CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage ); // select the maximum ROI in the image// with the width and height divisible by 2cvSetImageROI(timg, cvRect( 0, 0, sz.width, sz.height ));// down-scale and upscale the image to filter out the noisecvPyrDown(timg, pyr, 7 );cvPyrUp(pyr, timg, 7 );tgray = cvCreateImage( sz, 8, 1 );// find squares in every color plane of the imagefor( c = 0; c < 3; c++ ){// extract the c-th color planecvSetImageCOI(timg, c+1 );cvCopy(timg, tgray, 0 );// try several threshold levelsfor( l = 0; l < N; l++ ){// hack: use Canny instead of zero threshold level.// Canny helps to catch squares with gradient shadingif( l == 0 ){// apply Canny. Take the upper threshold from slider// and set the lower to 0 (which forces edges merging)cvCanny(tgray, gray, 0, thresh, 5 );// dilate canny output to remove potential// holes between edge segmentscvDilate( gray, gray, 0, 1 );}else{// apply threshold if l!=0:// tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0cvThreshold(tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY ); }// find contours and store them all as a listcvFindContours( gray, storage, &contours, sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) ); // test each contourwhile( contours ){// approximate contour with accuracy proportional// to the contour perimeterresult = cvApproxPoly( contours, sizeof(CvContour), storage,CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 ); // square contours should have 4 vertices after approximation// relatively large area (to filter out noisy contours)// and be convex.// Note: absolute value of an area is used because// area may be positive or negative - in accordance with the// contour orientationif( result->total == 4 &&fabs(cvContourArea(result,CV_WHOLE_SEQ)) > 1000 && cvCheckContourConvexity(result) ){s = 0;for(i = 0; i< 5; i++ ){// find minimum angle between joint// edges (maximum of cosine)if(i>= 2 ){t = fabs(angle((CvPoint*)cvGetSeqElem( result, i ),(CvPoint*)cvGetSeqElem( result, i-2 ),(CvPoint*)cvGetSeqElem( result, i-1 )));s = s >t ?s : t;}}// if cosines of all angles are small// (all angles are ~90 degree) then write quandrange // vertices to resultant sequenceif( s < 0.3 )for(i = 0; i< 4; i++ )cvSeqPush( squares,(CvPoint*)cvGetSeqElem( result, i ));}// take the next contourcontours = contours->h_next;}}}// release all the temporary imagescvReleaseImage(&gray );cvReleaseImage(&pyr );cvReleaseImage(&tgray );cvReleaseImage(&timg );return squares;}// the function draws all the squares in the image voiddrawSquares( IplImage* img, CvSeq* squares ){CvSeqReader reader;IplImage* cpy = cvCloneImage(img );inti;// initialize reader of the sequencecvStartReadSeq( squares, &reader, 0 );// read 4 sequence elements at a time (all vertices of a square) for(i = 0; i< squares->total; i += 4 ){CvPoint* rect = pt;int count = 4;// read 4 verticesmemcpy(pt, reader.ptr, squares->elem_size );CV_NEXT_SEQ_ELEM( squares->elem_size, reader );memcpy(pt + 1, reader.ptr, squares->elem_size );CV_NEXT_SEQ_ELEM( squares->elem_size, reader );memcpy(pt + 2, reader.ptr, squares->elem_size );CV_NEXT_SEQ_ELEM( squares->elem_size, reader );memcpy(pt + 3, reader.ptr, squares->elem_size );CV_NEXT_SEQ_ELEM( squares->elem_size, reader );// draw the square as a closed polylinecvPolyLine(cpy, &rect, &count, 1, 1, CV_RGB(0,255,0), 3, CV_AA, 0 ); }// show the resultant imagecvShowImage(wndname, cpy );cvReleaseImage(&cpy );}voidon_trackbar( int a ){if(img )drawSquares(img, findSquares4( img, storage ) );}char* names[] = { "pic1.png", "pic2.png", "pic3.png","pic4.png", "pic5.png", "pic6.png", 0 };int main(intargc, char** argv){inti, c;// create memory storage that will contain all the dynamic datastorage = cvCreateMemStorage(0);for(i = 0; names[i] != 0; i++ ){// load i-th imageimg0 = cvLoadImage( names[i], 1 );if( !img0 ){printf("Couldn't load %s/n", names[i] );continue;}img = cvCloneImage( img0 );// create window and a trackbar (slider) with parent "image" and set callback // (the slider regulates upper threshold, passed to Canny edge detector)cvNamedWindow(wndname, 1 );cvCreateTrackbar( "canny thresh", wndname, &thresh, 1000, on_trackbar ); // force the image processingon_trackbar(0);// wait for key.// Also the function cvWaitKey takes care of event processingc = cvWaitKey(0);// release both imagescvReleaseImage(&img );cvReleaseImage(&img0 );// clear memory storage - reset free space positioncvClearMemStorage( storage );if( c == 27 )break;}cvDestroyWindow(wndname );return 0;}#ifdef _EiCmain(1,"squares.c");#endif其它参考博客:1、/superdont/article/details/66642542、/%CE%C4%BF%A1%B5%C4%CF%A3%CD%FB/blog/item/3a5cb207 9158b304738b65f2.html#include <cv.h>#include <highgui.h>#include <math.h>int main(){IplImage* src;if( (src=cvLoadImage("5.bmp", 1)) != 0){IplImage* dst = cvCreateImage( cvGetSize(src), 8, 1 );IplImage* color_dst = cvCreateImage( cvGetSize(src), 8, 3 );CvMemStorage* storage = cvCreateMemStorage(0);//存储检测到线段,当然可以是N*1的矩阵数列,如果实际的直线数量多余N,那么最大可能数目的线段被返回CvSeq* lines = 0;inti;IplImage* src1=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);cvCvtColor(src, src1, CV_BGR2GRAY); //把src转换成灰度图像保存在src1中,注意进行边缘检测一定要换成灰度图cvCanny( src1, dst, 50, 200, 3 );//参数50,200的灰度变换cvCvtColor( dst, color_dst, CV_GRAY2BGR );#if 1lines = cvHoughLines2( dst, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 150, 0, 0 );//标准霍夫变换后两个参数为0,由于line_storage是内存空间,所以返回一个CvSeq序列结构的指针for( i = 0; i< lines->total; i++ ){float* line = (float*)cvGetSeqElem(lines,i);//用GetSeqElem得到直线float rho = line[0];float theta = line[1];//对于SHT和MSHT(标准变换)这里line[0],line[1]是rho(与像素相关单位的距离精度)和theta(弧度测量的角度精度)CvPoint pt1, pt2;double a = cos(theta), b = sin(theta);if( fabs(a) < 0.001 ){pt1.x = pt2.x = cvRound(rho);pt1.y = 0;pt2.y = color_dst->height;}else if( fabs(b) < 0.001 ){pt1.y = pt2.y = cvRound(rho);pt1.x = 0;pt2.x = color_dst->width;}else{pt1.x = 0;pt1.y = cvRound(rho/b);pt2.x = cvRound(rho/a);pt2.y = 0;}cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, 8 );}#elselines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 80, 30, 10 );for( i = 0; i< lines->total; i++ ){CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, 8 );}#endifcvNamedWindow( "Source", 1 );cvShowImage( "Source", src );cvNamedWindow( "Hough", 1 );cvShowImage( "Hough", color_dst );cvWaitKey(0);}}line_storage检测到的线段存储仓. 可以是内存存储仓(此种情况下,一个线段序列在存储仓中被创建,并且由函数返回),或者是包含线段参数的特殊类型(见下面)的具有单行/单列的矩阵(CvMat*)。

pythonopencv圆、椭圆与任意多边形的绘制实例详解

pythonopencv圆、椭圆与任意多边形的绘制实例详解

pythonopencv圆、椭圆与任意多边形的绘制实例详解圆形的绘制 :OpenCV中使⽤circle(img,center,radius,color,thickness=None,lineType=None,shift=None)函数来绘制圆形import cv2import numpy as npimage=np.zeros((400,400,3),np.uint8)cv2.circle(image,(200,200),50,(0,0,255),2) #画圆'''参数2 center:必选参数。

圆⼼坐标参数3 radius:必选参数。

圆形半径参数4 color:必选参数。

⽤于设置待绘制圆形的颜⾊参数5 thickness:可选参数。

当该参数为正数时,表⽰待绘制圆形轮廓的粗细;当该参数为负值时,表⽰待绘制圆形为实⼼圆,即填充的圆形参数6 lineType:可选参数。

⽤于设置线段的类型,可选8(8邻接连接线-默认)、4(4邻接连接线)和cv2.LINE_AA 为抗锯齿'''cv2.imshow('image',image)cv2.waitKey()椭圆的绘制:OpenCV中使⽤ellipse(img,center,axes,angle,startAngle,endAngle,color,thickness=None,lineType=None,shift=None)函数绘制椭圆import cv2import numpy as npimage=np.zeros((400,400,3),np.uint8)cv2.ellipse(image,(200,200),(100,150),0,30,360,(0,255,0),-1) #画椭圆'''参数2 center:必选参数。

⽤于设置待绘制椭圆的中⼼坐标,确定椭圆的位置参数3 axes:必选参数。

Opencv中函数的用法

Opencv中函数的用法

1、cvLoadImage:将图像文件加载至内存;2、cvNamedWindow:在屏幕上创建一个窗口;3、cvShowImage:在一个已创建好的窗口中显示图像;4、cvWaitKey:使程序暂停,等待用户触发一个按键操作;5、cvReleaseImage:释放图像文件所分配的内存;6、cvDestroyWindow:销毁显示图像文件的窗口;7、cvCreateFileCapture:通过参数设置确定要读入的AVI文件;8、cvQueryFrame:用来将下一帧视频文件载入内存;9、cvReleaseCapture:释放CvCapture结构开辟的内存空间;10、cvCreateTrackbar:创建一个滚动条;11、cvSetCaptureProperty:设置CvCapture对象的各种属性;12、cvGetCaptureProperty:查询CvCapture对象的各种属性;13、cvGetSize:当前图像结构的大小;14、cvSmooth:对图像进行平滑处理;15、cvPyrDown:图像金字塔,降采样,图像缩小为原来四分之一;16、cvCanny:Canny边缘检测;17、cvCreateCameraCapture:从摄像设备中读入数据;18、cvCreateVideoWriter:创建一个写入设备以便逐帧将视频流写入视频文件;搜索19、cvWriteFrame:逐帧将视频流写入文件;20、cvReleaseVideoWriter:释放CvVideoWriter结构开辟的内存空间;21、CV_MAT_ELEM:从矩阵中得到一个元素;22、cvAbs:计算数组中所有元素的绝对值;23、cvAbsDiff:计算两个数组差值的绝对值;24、cvAbsDiffS:计算数组和标量差值的绝对值;25、cvAdd:两个数组的元素级的加运算;26、cvAddS:一个数组和一个标量的元素级的相加运算;27、cvAddWeighted:两个数组的元素级的加权相加运算(alpha运算);28、cvAvg:计算数组中所有元素的平均值;29、cvAvgSdv:计算数组中所有元素的绝对值和标准差;30、cvCalcCovarMatrix:计算一组n维空间向量的协方差;31、cvCmp:对两个数组中的所有元素运用设置的比较操作;32、cvCmpS:对数组和标量运用设置的比较操作;33、cvConvertScale:用可选的缩放值转换数组元素类型;34、cvCopy:把数组中的值复制到另一个数组中;35、cvCountNonZero:计算数组中非0值的个数;36、cvCrossProduct:计算两个三维向量的向量积(叉积);37、cvCvtColor:将数组的通道从一个颜色空间转换另外一个颜色空间;38、cvDet:计算方阵的行列式;39、cvDiv:用另外一个数组对一个数组进行元素级的除法运算;40、cvDotProduct:计算两个向量的点积;41、cvEigenVV:计算方阵的特征值和特征向量;42、cvFlip:围绕选定轴翻转;43、cvGEMM:矩阵乘法;44、cvGetCol:从一个数组的列中复制元素;45、cvGetCols:从数据的相邻的多列中复制元素;46、cvGetDiag:复制数组中对角线上的所有元素;47、cvGetDims:返回数组的维数;48、cvGetDimSize:返回一个数组的所有维的大小;49、cvGetRow:从一个数组的行中复制元素值;50、cvGetRows:从一个数组的多个相邻的行中复制元素值;51、cvGetSize:得到二维的数组的尺寸,以CvSize返回;52、cvGetSubRect:从一个数组的子区域复制元素值;53、cvInRange:检查一个数组的元素是否在另外两个数组中的值的范围内;54、cvInRangeS:检查一个数组的元素的值是否在另外两个标量的范围内;55、cvInvert:求矩阵的逆;56、cvMahalonobis:计算两个向量间的马氏距离;57、cvMax:在两个数组中进行元素级的取最大值操作;58、cvMaxS:在一个数组和一个标量中进行元素级的取最大值操作;59、cvMerge:把几个单通道图像合并为一个多通道图像;60、cvMin:在两个数组中进行元素级的取最小值操作;61、cvMinS:在一个数组和一个标量中进行元素级的取最小值操作;62、cvMinMaxLoc:寻找数组中的最大最小值;63、cvMul:计算两个数组的元素级的乘积(点乘);64、cvNot:按位对数组中的每一个元素求反;65、cvNormalize:将数组中元素进行归一化;66、cvOr:对两个数组进行按位或操作;67、cvOrs:在数组与标量之间进行按位或操作;68、cvReduce:通过给定的操作符将二维数组简为向量;69、cvRepeat:以平铺的方式进行数组复制;70、cvSet:用给定值初始化数组;71、cvSetZero:将数组中所有元素初始化为0;72、cvSetIdentity:将数组中对角线上的元素设为1,其他置0;73、cvSolve:求出线性方程组的解;74、cvSplit:将多通道数组分割成多个单通道数组;75、cvSub:两个数组元素级的相减;76、cvSubS:元素级的从数组中减去标量;77、cvSubRS:元素级的从标量中减去数组;78、cvSum:对数组中的所有元素求和;79、cvSVD:二维矩阵的奇异值分解;80、cvSVBkSb:奇异值回代计算;81、cvTrace:计算矩阵迹;82、cvTranspose:矩阵的转置运算;83、cvXor:对两个数组进行按位异或操作;84、cvXorS:在数组和标量之间进行按位异或操作;85、cvZero:将所有数组中的元素置为0;86、cvConvertScaleAbs:计算可选的缩放值的绝对值之后再转换数组元素的类型;87、cvNorm:计算数组的绝对范数,绝对差分范数或者相对差分范数;88、cvAnd:对两个数组进行按位与操作;89、cvAndS:在数组和标量之间进行按位与操作;90、cvScale:是cvConvertScale的一个宏,可以用来重新调整数组的内容,并且可以将参数从一种数据类型转换为另一种;91、cvT:是函数cvTranspose的缩写;92、cvLine:画直线;93、cvRectangle:画矩形;94、cvCircle:画圆;95、cvEllipse:画椭圆;96、cvEllipseBox:使用外接矩形描述椭圆;97、cvFillPoly、cvFillConvexPoly、cvPolyLine:画多边形;98、cvPutText:在图像上输出一些文本;99、cvInitFont:采用一组参数配置一些用于屏幕输出的基本个特定字体;100、cvSave:矩阵保存;101、cvLoad:矩阵读取;102、cvOpenFileStorage:为读/写打开存储文件;103、cvReleaseFileStorage:释放存储的数据;104、cvStartWriteStruct:开始写入新的数据结构;105、cvEndWriteStruct:结束写入数据结构;106、cvWriteInt:写入整数型;107、cvWriteReal:写入浮点型;108、cvWriteString:写入字符型;109、cvWriteComment:写一个XML或YAML的注释字串;110、cvWrite:写一个对象;111、cvWriteRawData:写入多个数值;112、cvWriteFileNode:将文件节点写入另一个文件存储器;113、cvGetRootFileNode:获取存储器最顶层的节点;114、cvGetFileNodeByName:在映图或存储器中找到相应节点;115、cvGetHashedKey:为名称返回一个惟一的指针;116、cvGetFileNode:在映图或文件存储器中找到节点;117、cvGetFileNodeName:返回文件的节点名;118、cvReadInt:读取一个无名称的整数型;119、cvReadIntByName:读取一个有名称的整数型;120、cvReadReal:读取一个无名称的浮点型;121、cvReadRealByName:读取一个有名称的浮点型;122、cvReadString:从文件节点中寻找字符串;123、cvReadStringByName:找到一个有名称的文件节点并返回它;124、cvRead:将对象解码并返回它的指针;125、cvReadByName:找到对象并解码;126、cvReadRawData:读取多个数值;127、cvStartReadRawData:初始化文件节点序列的读取;128、cvReadRawDataSlice:读取文件节点的内容;129、cvGetModuleInfo:检查IPP库是否已经正常安装并且检验运行是否正常;130、cvResizeWindow:用来调整窗口的大小;131、cvSaveImage:保存图像;132、cvMoveWindow:将窗口移动到其左上角为x,y的位置;133、cvDestroyAllWindow:用来关闭所有窗口并释放窗口相关的内存空间;134、cvGetTrackbarPos:读取滑动条的值;135、cvSetTrackbarPos:设置滑动条的值;136、cvGrabFrame:用于快速将视频帧读入内存;137、cvRetrieveFrame:对读入帧做所有必须的处理;138、cvConvertImage:用于在常用的不同图像格式之间转换;139、cvErode:形态腐蚀;140、cvDilate:形态学膨胀;141、cvMorphologyEx:更通用的形态学函数;142、cvFloodFill:漫水填充算法,用来进一步控制哪些区域将被填充颜色;143、cvResize:放大或缩小图像;144、cvPyrUp:图像金字塔,将现有的图像在每个维度上都放大两倍;145、cvPyrSegmentation:利用金字塔实现图像分割;146、cvThreshold:图像阈值化;147、cvAcc:可以将8位整数类型图像累加为浮点图像;148、cvAdaptiveThreshold:图像自适应阈值;149、cvFilter2D:图像卷积;150、cvCopyMakeBorder:将特定的图像轻微变大,然后以各种方式自动填充图像边界;151、cvSobel:图像边缘检测,Sobel算子;152、cvLaplace:拉普拉斯变换、图像边缘检测;。

opencvsharp_多边形的最小内接矩形_概述及解释说明

opencvsharp_多边形的最小内接矩形_概述及解释说明

opencvsharp 多边形的最小内接矩形概述及解释说明1. 引言1.1 概述本文将介绍OpencvSharp中的多边形的最小内接矩形,并解释其实现方法和应用场景。

随着数字图像处理技术的不断发展,越来越多的应用需要对图像中的多边形进行分析和处理。

而多边形的最小内接矩形是一种重要的几何特征,它可以帮助我们更好地理解和描述图像中的各种物体。

1.2 文章结构本文分为五个部分:引言、OpencvSharp多边形的最小内接矩形、实现方法与示例说明、应用场景与案例分析以及结论与展望。

在引言部分,我们将对文章进行概述,并介绍文章结构。

在第二部分,我们将详细介绍OpencvSharp库以及多边形和内接矩形的概念解释。

然后,在第三部分,我们将讨论如何安装OpencvSharp库,并给出读取和绘制多边形图像数据以及计算多边形最小内接矩形的具体实现方法。

在第四部分,我们将通过实际案例来说明该技术在图像处理领域中的应用场景。

最后,在第五部分,我们将总结整篇文章并提出进一步研究的方向。

1.3 目的本文旨在提供一个关于OpencvSharp多边形最小内接矩形的全面概述和解释说明。

通过该文章,读者将了解到OpencvSharp库在多边形处理中的重要性,并能掌握计算多边形最小内接矩形的方法。

此外,本文还将介绍一些实际应用案例,帮助读者更好地理解该技术在图像处理领域中的实际应用价值。

最后,我们希望通过本文的阐述能够激发读者进一步研究和探索这一领域,并为未来的相关研究提供有益的借鉴。

2. OpencvSharp 多边形的最小内接矩形2.1 OpencvSharp 简介OpencvSharp是一个基于C#的开源计算机视觉库,它提供了丰富的图像处理和计算机视觉函数。

该库是对OpenCV库的封装,在.NET平台上提供了一种简单而强大的方式来进行图像处理和分析。

2.2 多边形和内接矩形的概念解释在数学和几何学中,多边形是由若干个连续直线段组成的封闭图形。

C语言实现opencv提取直线、轮廓及ROI实例详解

C语言实现opencv提取直线、轮廓及ROI实例详解

C语⾔实现opencv提取直线、轮廓及ROI实例详解⼀、Canny检测轮廓在上⼀篇⽂章中有提到sobel边缘检测,并重写了soble的C++代码让其与matlab中算法效果⼀致,⽽soble边缘检测是基于单⼀阈值的,我们不能兼顾到低阈值的丰富边缘和⾼阈值时的边缘缺失这两个问题。

⽽canny算⼦则很好的弥补了这⼀不⾜,从⽬前看来,canny边缘检测在做图像轮廓提取⽅⾯是最优秀的边缘检测算法。

canny边缘检测采⽤双阈值值法,⾼阈值⽤来检测图像中重要的、显著的线条、轮廓等,⽽低阈值⽤来保证不丢失细节部分,低阈值检测出来的边缘更丰富,但是很多边缘并不是我们关⼼的。

最后采⽤⼀种查找算法,将低阈值中与⾼阈值的边缘有重叠的线条保留,其他的线条都删除。

本篇⽂章中不对canny的算法原理作进⼀步说明,稍后会在图像处理算法相关的⽂章中详细介绍。

下⾯我们⽤OpenCV中的Canny函数来检测图像边缘int main(){Mat I=imread("../cat.png");cvtColor(I,I,CV_BGR2GRAY);Mat contours;Canny(I,contours,125,350);threshold(contours,contours,128,255,THRESH_BINARY);namedWindow("Canny");imshow("Canny",contours);waitKey();return 0;}显⽰效果如下:⼆、直线检测⽤到的是霍夫变换检测直线的算法直线在图像中出现的频率⾮常之⾼,⽽直线作为图像的特征对于基本内容的图像分析有着很重要的作⽤,本⽂通过OpenCV中的hough变换来检测图像中的线条。

我们先看最基本的Hough变换函数HoughLines,它的原型如下:void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 );它的输⼊是⼀个⼆值的轮廓图像,往往是边缘检测得到的结果图像;它的输出是⼀个包含多个Vec2f点的数组,数组中的每个元素是⼀个⼆元浮点数据对<rou,theta>,rou代表直线离坐标原点的距离,theta代表⾓度。

opencv库常用函数

opencv库常用函数

opencv库常⽤函数常⽤opencv函数:1、cv2.line():画线——参数依次为:图⽚路径,起点和终点坐标值,颜⾊(rgb),线条宽度(像素)2、dst = cvtColor(src,code,dst=None,dstCn=None):颜⾊空间转换函数——参数依次为(原图像,color转化代码,输出图像,输出通道), 返回转换后的图像3、ret, dst = cv2.threshold(src, thresh, maxval, type):固定阈值⼆值化——src:输⼊图,只能输⼊单通道图像,通常来说为灰度图dst:输出图thresh:阈值maxval:当像素值超过了阈值(或者⼩于阈值,根据type来决定),所赋予的值type:⼆值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV4、cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]]) :查找检测物体的轮廓opencv2返回两个值:contours:hierarchy。

注:opencv3会返回三个值,分别是img, countours, hierarchy参数:第⼀个参数是寻找轮廓的图像;第⼆个参数表⽰轮廓的检索模式,有四种(本⽂介绍的都是新的cv2接⼝):cv2.RETR_EXTERNAL 表⽰只检测外轮廓cv2.RETR_LIST 检测的轮廓不建⽴等级关系cv2.RETR_CCOMP 建⽴两个等级的轮廓,上⾯的⼀层为外边界,⾥⾯的⼀层为内孔的边界信息。

如果内孔内还有⼀个连通物体,这个物体的边界也在顶层。

cv2.RETR_TREE 建⽴⼀个等级树结构的轮廓。

第三个参数method为轮廓的近似办法cv2.CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1cv2.CHAIN_APPROX_SIMPLE 压缩⽔平⽅向,垂直⽅向,对⾓线⽅向的元素,只保留该⽅向的终点坐标,例如⼀个矩形轮廓只需4个点来保存轮廓信息cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 使⽤teh-Chinl chain 近似算法返回值cv2.findContours()函数返回两个值,⼀个是轮廓本⾝,还有⼀个是每条轮廓对应的属性。

OpenCV直线、圆形和椭圆详细解释

OpenCV直线、圆形和椭圆详细解释

直线cvLine()是绘图函数中最简单的,只需用Bresenham算法[Bresenham65]画一条线:void cvLine(CvArr* array,CvPoint pt1,CvPoint pt2,CvScalar color,int thickness = 1,int connectivity = 8);cvLine()函数中的第一个属性是CvArr*。

在这里,它一般为一个图像类型的指针IplImage*。

随后两个CvPoint是一种简单的数据结构,它只包括整型变量x 和y。

我们可以用CvPoint(int x, int y)函数快速地构造一个CvPoint类型的变量,这样可以方便地把两个整型变量值赋给CvPoint数据结构。

下一个属性是CvScalar类型的颜色变量。

CvScalar也是一种数据结构,定义如下所示:typdef struct {double val[4];} CvScalar;可以看出,这种结构只是四个双精度浮点型变量的集合。

在这里,前三个分别代表红,绿,蓝通道;没有用到第四个(它只在适当的时候用于alpha通道)。

一个常用的便捷宏指令是CV_RGB(r, g, b),该指令采用三个数字作为参数并将其封装到CvScalar。

接下来的两个属性是可选的。

thickness是线的粗细(像素),connectivity被设为反走样模式,默认值为“8连通”,这种是较为平滑不会走样的线型。

也可以设置为“4连通”,这样的话,斜线会产生重叠以致看上去过于粗重,不过画起来速度要快得多。

cvRectangle()和cvLine()几乎同样便捷。

cvRectangle()用于画矩形。

除了没有connectivity参数,它和cvLine()的其他参数都是一样的。

因为由此产生的矩形总是平行与X和Y轴。

利用cvRectangle(),我们只需给出两个对顶点,OpenCV便于画出一个矩形。

void cvRectangle(CvArr* array,CvPoint pt1,CvPoint pt2,CvScalar color,int thickness = 1);圆形和椭圆画圆同样简单,其参数与前相同。

opencv findcontours用法

opencv findcontours用法

opencv findcontours用法opencv是一个广泛使用的计算机视觉库,它可以帮助开发人员创建高质量的图像和视频处理应用程序。

其中,findContours函数是opencv中的一个常用函数,用于查找图像中的复杂图形轮廓。

以下是使用opencv findContours函数查找图像中的轮廓的一般步骤:1. 导入所需的库并设置环境变量首先,需要导入opencv库并设置环境变量,以便可以使用opencv findContours函数。

可以使用以下命令:```#include <opencv2/opencv.hpp>```2. 创建输入文件接下来,需要创建一个输入文件,用于存储要查找轮廓的图像数据。

可以使用以下命令:```#include <opencv2/core/core.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/videoio/videoio.hpp>int main(int argc, char** argv) {// Create input filecv::Mat inputImage = cv::imreadimread("inputImage.jpg",cv::IMREAD_GRAYSCALE);// Create output filecv::Mat outputImage = cv::Mat(inputImage.rows, inputImage.cols, CV_8UC3);cv::imwrite("contours.jpg", outputImage);return 0;}```在上面的示例中,我们使用了cv::imreadimread函数来读取图像文件,并使用cv::imwrite函数来创建输出文件。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

在MFC中我们经常会画线、矩形、椭圆、多边形等几何结构,opencv为我们提供了已经封装好的函数来实现该功能,而且简单方便。

下面提供一下例子,是Opencv安装以后自带的小程序,学习完现在的程序你可以学会以下知识:(1)生成随机数,使用RNG类(2)画线(3)画矩形(4)画椭圆(5)画圆(6)输出文字、文本(7)如果不熟悉Opencv的还能学会point结构体的使用,Scalar结构使用。

具体可以看下面的小例子。

在vs2010下运行一下就会明白了!#include "stdafx.h"#include "opencv2/core/core.hpp"#include "opencv2/highgui/highgui.hpp"#include <stdio.h>using namespace cv;void help(){printf("\nThis program demonstrates OpenCV drawing and text output functions.\n""Usage:\n"" ./drawing\n");}static Scalar randomColor(RNG& rng){int icolor = (unsigned)rng;return Scalar(icolor&255, (icolor>>8)&255, (icolor>>16)&255);}int main(){help();char wndname[] = "Drawing Demo";const int NUMBER = 100;const int DELAY = 5;int lineType = CV_AA; // change it to 8 to see non-antialiased graphicsint i, width = 1000, height = 700;int x1 = -width/2, x2 = width*3/2, y1 = -height/2, y2 = height*3/2;RNG rng(0xFFFFFFFF);Mat image = Mat::zeros(height, width, CV_8UC3);imshow(wndname, image);waitKey(DELAY);for (i = 0; i < NUMBER; i++){Point pt1, pt2;pt1.x = rng.uniform(x1, x2);pt1.y = rng.uniform(y1, y2);pt2.x = rng.uniform(x1, x2);pt2.y = rng.uniform(y1, y2);line( image, pt1, pt2, randomColor(rng), rng.uniform(1,10), lineType );imshow(wndname, image);if(waitKey(DELAY) >= 0)return 0;}for (i = 0; i < NUMBER; i++){Point pt1, pt2;pt1.x = rng.uniform(x1, x2);pt1.y = rng.uniform(y1, y2);pt2.x = rng.uniform(x1, x2);pt2.y = rng.uniform(y1, y2);int thickness = rng.uniform(-3, 10);rectangle( image, pt1, pt2, randomColor(rng), MAX(thickness, -1), lineType ); imshow(wndname, image);if(waitKey(DELAY) >= 0)return 0;}for (i = 0; i < NUMBER; i++){Point center;center.x = rng.uniform(x1, x2);center.y = rng.uniform(y1, y2);Size axes;axes.width = rng.uniform(0, 200);axes.height = rng.uniform(0, 200);double angle = rng.uniform(0, 180);ellipse( image, center, axes, angle, angle - 100, angle + 200,randomColor(rng), rng.uniform(-1,9), lineType );imshow(wndname, image);if(waitKey(DELAY) >= 0)return 0;}for (i = 0; i< NUMBER; i++){Point pt[2][3];pt[0][0].x = rng.uniform(x1, x2);pt[0][0].y = rng.uniform(y1, y2);pt[0][1].x = rng.uniform(x1, x2);pt[0][1].y = rng.uniform(y1, y2);pt[0][2].x = rng.uniform(x1, x2);pt[0][2].y = rng.uniform(y1, y2);pt[1][0].x = rng.uniform(x1, x2);pt[1][0].y = rng.uniform(y1, y2);pt[1][1].x = rng.uniform(x1, x2);pt[1][1].y = rng.uniform(y1, y2);pt[1][2].x = rng.uniform(x1, x2);pt[1][2].y = rng.uniform(y1, y2);const Point* ppt[2] = {pt[0], pt[1]};int npt[] = {3, 3};polylines(image, ppt, npt, 2, true, randomColor(rng), rng.uniform(1,10), lineType); imshow(wndname, image);if(waitKey(DELAY) >= 0)return 0;}for (i = 0; i< NUMBER; i++){Point pt[2][3];pt[0][0].x = rng.uniform(x1, x2);pt[0][0].y = rng.uniform(y1, y2);pt[0][1].x = rng.uniform(x1, x2);pt[0][1].y = rng.uniform(y1, y2);pt[0][2].x = rng.uniform(x1, x2);pt[0][2].y = rng.uniform(y1, y2);pt[1][0].x = rng.uniform(x1, x2);pt[1][0].y = rng.uniform(y1, y2);pt[1][1].x = rng.uniform(x1, x2);pt[1][1].y = rng.uniform(y1, y2);pt[1][2].x = rng.uniform(x1, x2);pt[1][2].y = rng.uniform(y1, y2);const Point* ppt[2] = {pt[0], pt[1]};int npt[] = {3, 3};fillPoly(image, ppt, npt, 2, randomColor(rng), lineType);imshow(wndname, image);if(waitKey(DELAY) >= 0)return 0;}for (i = 0; i < NUMBER; i++){Point center;center.x = rng.uniform(x1, x2);center.y = rng.uniform(y1, y2);circle(image, center, rng.uniform(0, 300), randomColor(rng),rng.uniform(-1, 9), lineType);imshow(wndname, image);if(waitKey(DELAY) >= 0)return 0;}for (i = 1; i < NUMBER; i++){Point org;org.x = rng.uniform(x1, x2);org.y = rng.uniform(y1, y2);putText(image, "Testing text rendering", org, rng.uniform(0,8),rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType); imshow(wndname, image);if(waitKey(DELAY) >= 0)return 0;}Size textsize = getTextSize("OpenCV forever!", CV_FONT_HERSHEY_COMPLEX, 3, 5, 0);Point org((width - textsize.width)/2, (height - textsize.height)/2);Mat image2;for( i = 0; i < 255; i += 2 ){image2 = image - Scalar::all(i);putText(image2, "OpenCV forever!", org, CV_FONT_HERSHEY_COMPLEX, 3,Scalar(i, i, 255), 5, lineType);imshow(wndname, image2);if(waitKey(DELAY) >= 0)return 0;}waitKey();return 0;}。

相关文档
最新文档