OpenCV学习笔记: 快速入门例程
2013-08-14 20:26
495 查看
先期基础:
————————————————————————————
Main函数参数argc,argv说明
C/C++语言中的main函数,经常带有参数argc,argv,如下:
int main(int argc, char** argv)
int main(int argc, char* argv[])
这两个参数的作用: argc 是指命令行输入参数的个数(以空白符分隔) argv存储了所有的命令行参数 假如你的程序是hello.exe,如果在命令行运行该程序,(首先应该在命令行下用 cd 命令进入到 hello.exe 文件所在目录) 运行命令为:
hello.exe Shiqi Yu
那么,argc的值是 3,argv[0]是"hello.exe",argv[1]是"Shiqi",argv[2]是"Yu"。
—————————————————————————————
自opencv2.2开始,opencv库便被划分为多个模块。这些模块编译成库文件后,位于lib文件夹中。
opencv_core 包含核心功能,尤其是底层数据结构和算法函数
opencv_imgproc 包含图像处理函数
opencv_highgui 包含读写图像及视频的函数,以及操作图形用户界面函数
opencv_features2d 包含兴趣点检测子、描述子以及兴趣点匹配框架
opencv_calib3d 包含相机标定,双目几何估算以及立体视觉函数
opencv_video 包含运动估算、特征跟踪以及前景提取函数与类
opencv_objectect 包括物体检测函数,如脸部与行人检测
———————————————————
OpenCV 命名规则
(1) 函数名:
cvActionTargetMod(...)
Action = 核心功能(core functionality) (e.g. set, create)
Target = 目标图像区域(target image area) (e.g. contour, polygon)
Mod = (可选的)调整语(optional modifiers) (e.g. argument type)
(2) 矩阵数据类型:
CV_<bit_depth>(S|U|F)C<number_of_channels>
S = 符号整型
U = 无符号整型
F = 浮点型
E.g. : CV_8UC1 是指一个8位无符号整型单通道矩阵,
CV_32FC2是指一个32位浮点型双通道矩阵.
(3) 图像数据类型:
IPL_DEPTH_<bit_depth>(S|U|F)
E.g.: IPL_DEPTH_8U 图像像素数据是8位无符号整型.
IPL_DEPTH_32F图像像素数据是32位浮点型.
(4) 头文件:
#include <cv.h>
#include <cvaux.h>
#include <highgui.h>
#include <ml.h>
#include <cxcore.h> // 一般不需要,cv.h 内已包含该头文件
_________________________________________________
指向const对象的指针:
若指针指向const对象,则不允许使用指针来改变其所指的const值。
为了保证这个特性,C++强制要求指向const对象的指针也必须具有const特性
const double * cptr;(
这里的cptr是一个指向double类型const对象的指针,const限定了cptr指针所指向的对象类型,而并非cptr本身,即cptr本身并不是const。在定义时不需要对它进行初始化,若需要允许给cptr重新赋值,使其指向另一个const对象,但不能通过cptr修改其所指向对象的值。
在实际应用中,指向const的指针常用作函数的形参,将形参定义为指向const的指针以确保传递给函数的实际对象在函数中不因为形参而被修改。
第一个例程:很简单,图像的读取和显示
第二个例程:图像缩放
函数原型:
void cvResize(
const CvArr* src,
CvArr* dst,
int interpolation=CV_INTER_LINEAR
);
函数说明:
第一个参数表示输入图像。第二个参数表示输出图像。第三个参数表示插值方法,可以有以下四种:
CV_INTER_NN - 最近邻插值,
CV_INTER_LINEAR - 双线性插值 (缺省使用)
CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法..
CV_INTER_CUBIC - 立方插值.
函数原型:
IplImage* cvCreateImage(CvSize size, int depth, int channels);
函数说明:
第一个参数表示图像的大小。第二个参数表示图像的深度,可以为IPL_DEPTH_8U,IPL_DEPTH_16U等等。第三个参数表示图像的通道数。
第三个例程:图像边缘检测
第四个例程: 图像二值化
第五个例程:轮廓检测
本篇介绍轮廓检测,轮廓检测的原理通俗的说就是掏空内部点,比如原图中有3*3的矩形点。那么就可以将中间的那一点去掉。在OpenCV中使用轮廓检测是非常方便。直接使用cvFindContours函数就能完成对图像轮廓的检测。下面就来看看这个函数的用法。
函数原型:
函数说明:
第一个参数表示输入图像,必须为一个8位的二值图像。
第二参数表示存储轮廓的容器。为CvMemStorage类型,定义在OpenCV的\core\types_c.h中。
第三个参数为输出参数,这个参数将指向用来存储轮廓信息的链表表头。
第四个参数表示存储轮廓链表的表头大小,当第六个参数传入CV_CHAIN_CODE时,要设置成sizeof(CvChain),其它情况统一设置成sizeof(CvContour)。
第五个参数为轮廓检测的模式,有如下取值:
CV_RETR_EXTERNAL:只检索最外面的轮廓;
CV_RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;
CV_RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
CV_RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次,可以参见下图。
第六个参数用来表示轮廓边缘的近似方法的,常用值如下所示:
CV_CHAIN_CODE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
CV_CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
第七个参数表示偏移量,比如你要从图像的(100, 0)开始进行轮廓检测,那么就传入(100,
0)。
使用cvFindContours函数能检测出图像的轮廓,将轮廓绘制出来则需要另一函数——cvDrawContours来配合了。下面介绍cvDrawContours函数。
函数原型:
第一个参数表示输入图像,函数将在这张图像上绘制轮廓。
第二个参数表示指向轮廓链表的指针。
第三个参数和第四个参数表示颜色,绘制时会根据轮廓的层次来交替使用这二种颜色。
第五个参数表示绘制轮廓的最大层数,如果是0,只绘制contour;如果是1,追加绘制和contour同层的所有轮廓;如果是2,追加绘制比contour低一层的轮廓,以此类推;如果值是负值,则函数并不绘制contour后的轮廓,但是将画出其子轮廓,一直到abs(max_level)
- 1层。
第六个参数表示轮廓线的宽度,如果为CV_FILLED则会填充轮廓内部。
第七个参数表示轮廓线的类型。
第八个参数表示偏移量,如果传入(10,20),那绘制将从图像的(10,20)处开始。
————————————————————————————
Main函数参数argc,argv说明
C/C++语言中的main函数,经常带有参数argc,argv,如下:
int main(int argc, char** argv)
int main(int argc, char* argv[])
这两个参数的作用: argc 是指命令行输入参数的个数(以空白符分隔) argv存储了所有的命令行参数 假如你的程序是hello.exe,如果在命令行运行该程序,(首先应该在命令行下用 cd 命令进入到 hello.exe 文件所在目录) 运行命令为:
hello.exe Shiqi Yu
那么,argc的值是 3,argv[0]是"hello.exe",argv[1]是"Shiqi",argv[2]是"Yu"。
—————————————————————————————
OpenCV模块
自opencv2.2开始,opencv库便被划分为多个模块。这些模块编译成库文件后,位于lib文件夹中。opencv_core 包含核心功能,尤其是底层数据结构和算法函数
opencv_imgproc 包含图像处理函数
opencv_highgui 包含读写图像及视频的函数,以及操作图形用户界面函数
opencv_features2d 包含兴趣点检测子、描述子以及兴趣点匹配框架
opencv_calib3d 包含相机标定,双目几何估算以及立体视觉函数
opencv_video 包含运动估算、特征跟踪以及前景提取函数与类
opencv_objectect 包括物体检测函数,如脸部与行人检测
———————————————————
OpenCV 命名规则
(1) 函数名:
cvActionTargetMod(...)
Action = 核心功能(core functionality) (e.g. set, create)
Target = 目标图像区域(target image area) (e.g. contour, polygon)
Mod = (可选的)调整语(optional modifiers) (e.g. argument type)
(2) 矩阵数据类型:
CV_<bit_depth>(S|U|F)C<number_of_channels>
S = 符号整型
U = 无符号整型
F = 浮点型
E.g. : CV_8UC1 是指一个8位无符号整型单通道矩阵,
CV_32FC2是指一个32位浮点型双通道矩阵.
(3) 图像数据类型:
IPL_DEPTH_<bit_depth>(S|U|F)
E.g.: IPL_DEPTH_8U 图像像素数据是8位无符号整型.
IPL_DEPTH_32F图像像素数据是32位浮点型.
(4) 头文件:
#include <cv.h>
#include <cvaux.h>
#include <highgui.h>
#include <ml.h>
#include <cxcore.h> // 一般不需要,cv.h 内已包含该头文件
_________________________________________________
指向const对象的指针:
若指针指向const对象,则不允许使用指针来改变其所指的const值。
为了保证这个特性,C++强制要求指向const对象的指针也必须具有const特性
const double * cptr;(
const char *pstrImageName = "c:\\Baboon.jpg";)
这里的cptr是一个指向double类型const对象的指针,const限定了cptr指针所指向的对象类型,而并非cptr本身,即cptr本身并不是const。在定义时不需要对它进行初始化,若需要允许给cptr重新赋值,使其指向另一个const对象,但不能通过cptr修改其所指向对象的值。
在实际应用中,指向const的指针常用作函数的形参,将形参定义为指向const的指针以确保传递给函数的实际对象在函数中不因为形参而被修改。
第一个例程:很简单,图像的读取和显示
#include "stdafx.h" #include <string> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int _tmain(int argc, _TCHAR* argv[]) { string imagename="c:\\lena.jpg"; //要用绝对路径才行 //const char* imagename = "c:\\lena.jpg"; //从文件中读入图像 Mat img = imread(imagename); //如果读入图像失败 if(img.empty()) { fprintf(stderr, "Can not load image %s\n", imagename); return -1; } //显示图像 imshow("image", img); //此函数等待按键,按键盘任意键就返回 waitKey(); return 0; }
第二个例程:图像缩放
//功能:图像缩放实现 #include <opencv2/opencv.hpp> using namespace std; //隐藏控制台窗口 #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") int main() { const char *pstrImageName = "c:\\Baboon.jpg"; const char *pstrSaveImageName = "结果图.jpg"; const char *pstrWindowsSrcTitle = "Original image"; const char *pstrWindowsDstTitle = "Scaled image"; double fScale = 0.422; //缩放倍数 CvSize czSize; //目标图像尺寸 //从文件中读取图像 IplImage *pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED); IplImage *pDstImage = NULL; //计算目标图像大小 czSize.width = pSrcImage->width * fScale; czSize.height = pSrcImage->height * fScale; //创建图像并缩放 pDstImage = cvCreateImage(czSize, pSrcImage->depth, pSrcImage->nChannels); cvResize(pSrcImage, pDstImage, CV_INTER_AREA); //创建窗口 cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsDstTitle, CV_WINDOW_AUTOSIZE); //在指定窗口中显示图像 cvShowImage(pstrWindowsSrcTitle, pSrcImage); cvShowImage(pstrWindowsDstTitle, pDstImage); //等待按键事件 cvWaitKey(); //保存图片 cvSaveImage(pstrSaveImageName, pDstImage); cvDestroyWindow(pstrWindowsSrcTitle); cvDestroyWindow(pstrWindowsDstTitle); cvReleaseImage(&pSrcImage); cvReleaseImage(&pDstImage); return 0; }
函数介绍
cvResize 函数功能:图像大小变换
函数原型:void cvResize(
const CvArr* src,
CvArr* dst,
int interpolation=CV_INTER_LINEAR
);
函数说明:
第一个参数表示输入图像。第二个参数表示输出图像。第三个参数表示插值方法,可以有以下四种:
CV_INTER_NN - 最近邻插值,
CV_INTER_LINEAR - 双线性插值 (缺省使用)
CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法..
CV_INTER_CUBIC - 立方插值.
cvCreateImage 函数功能:创建图像
函数原型:IplImage* cvCreateImage(CvSize size, int depth, int channels);
函数说明:
第一个参数表示图像的大小。第二个参数表示图像的深度,可以为IPL_DEPTH_8U,IPL_DEPTH_16U等等。第三个参数表示图像的通道数。
第三个例程:图像边缘检测
//图像的Canny边缘检测 #include <opencv2/opencv.hpp> using namespace std; #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") IplImage *g_pSrcImage, *g_pCannyImg; const char *pstrWindowsCannyTitle = "边缘图"; //cvCreateTrackbar的回调函数 void on_trackbar(int threshold) { //canny边缘检测 cvCanny(g_pSrcImage, g_pCannyImg, threshold, threshold * 3, 3); cvShowImage(pstrWindowsCannyTitle, g_pCannyImg); } int main() { const char *pstrImageName = "C:\\Fruits.jpg"; const char *pstrWindowsSrcTitle = "Original image"; const char *pstrWindowsToolBar = "Threshold"; //从文件中载入图像的灰度图CV_LOAD_IMAGE_GRAYSCALE - 灰度图 g_pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_GRAYSCALE); g_pCannyImg = cvCreateImage(cvGetSize(g_pSrcImage), IPL_DEPTH_8U, 1); //创建窗口 cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsCannyTitle, CV_WINDOW_AUTOSIZE); //创建滑动条 int nThresholdEdge = 1; cvCreateTrackbar(pstrWindowsToolBar, pstrWindowsCannyTitle, &nThresholdEdge, 50, on_trackbar); //在指定窗口中显示图像 cvShowImage(pstrWindowsSrcTitle, g_pSrcImage); on_trackbar(1); //等待按键事件 cvWaitKey(); cvDestroyWindow(pstrWindowsSrcTitle); cvDestroyWindow(pstrWindowsCannyTitle); cvReleaseImage(&g_pSrcImage); cvReleaseImage(&g_pCannyImg); return 0; }
第四个例程: 图像二值化
//图像的二值化 #include <opencv2/opencv.hpp> using namespace std; #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") IplImage *g_pGrayImage = NULL; IplImage *g_pBinaryImage = NULL; const char *pstrWindowsBinaryTitle = "Binary Image"; void on_trackbar(int pos) { // 转为二值图 cvThreshold(g_pGrayImage, g_pBinaryImage, pos, 255, CV_THRESH_BINARY); // 显示二值图 cvShowImage(pstrWindowsBinaryTitle, g_pBinaryImage); } int main( int argc, char** argv ) { const char *pstrWindowsSrcTitle = "原图"; const char *pstrWindowsToolBarName = "二值图阈值"; // 从文件中加载原图 IplImage *pSrcImage = cvLoadImage("C:\\lena.jpg", CV_LOAD_IMAGE_UNCHANGED); // 转为灰度图 g_pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1); cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY); // 创建二值图 g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1); // 显示原图 cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsSrcTitle, pSrcImage); // 创建二值图窗口 cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE); // 滑动条 int nThreshold = 0; cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar); on_trackbar(1); cvWaitKey(0); cvDestroyWindow(pstrWindowsSrcTitle); cvDestroyWindow(pstrWindowsBinaryTitle); cvReleaseImage(&pSrcImage); cvReleaseImage(&g_pGrayImage); cvReleaseImage(&g_pBinaryImage); return 0; }
第五个例程:轮廓检测
本篇介绍轮廓检测,轮廓检测的原理通俗的说就是掏空内部点,比如原图中有3*3的矩形点。那么就可以将中间的那一点去掉。在OpenCV中使用轮廓检测是非常方便。直接使用cvFindContours函数就能完成对图像轮廓的检测。下面就来看看这个函数的用法。
cvFindContours 函数功能:对图像进行轮廓检测,这个函数将生成一条链表以保存检测出的各个轮廓信息,并传出指向这条链表表头的指针。
函数原型:int cvFindContours(CvArr* image, CvMemStorage* storage, CvSeq** first_contour, int header_size=sizeof(CvContour), int mode=CV_RETR_LIST, int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) );
函数说明:
第一个参数表示输入图像,必须为一个8位的二值图像。
第二参数表示存储轮廓的容器。为CvMemStorage类型,定义在OpenCV的\core\types_c.h中。
第三个参数为输出参数,这个参数将指向用来存储轮廓信息的链表表头。
第四个参数表示存储轮廓链表的表头大小,当第六个参数传入CV_CHAIN_CODE时,要设置成sizeof(CvChain),其它情况统一设置成sizeof(CvContour)。
第五个参数为轮廓检测的模式,有如下取值:
CV_RETR_EXTERNAL:只检索最外面的轮廓;
CV_RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;
CV_RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
CV_RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次,可以参见下图。
第六个参数用来表示轮廓边缘的近似方法的,常用值如下所示:
CV_CHAIN_CODE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
CV_CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
第七个参数表示偏移量,比如你要从图像的(100, 0)开始进行轮廓检测,那么就传入(100,
0)。
使用cvFindContours函数能检测出图像的轮廓,将轮廓绘制出来则需要另一函数——cvDrawContours来配合了。下面介绍cvDrawContours函数。
cvDrawContours 函数功能:在图像上绘制外部和内部轮廓
函数原型: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));
第一个参数表示输入图像,函数将在这张图像上绘制轮廓。
第二个参数表示指向轮廓链表的指针。
第三个参数和第四个参数表示颜色,绘制时会根据轮廓的层次来交替使用这二种颜色。
第五个参数表示绘制轮廓的最大层数,如果是0,只绘制contour;如果是1,追加绘制和contour同层的所有轮廓;如果是2,追加绘制比contour低一层的轮廓,以此类推;如果值是负值,则函数并不绘制contour后的轮廓,但是将画出其子轮廓,一直到abs(max_level)
- 1层。
第六个参数表示轮廓线的宽度,如果为CV_FILLED则会填充轮廓内部。
第七个参数表示轮廓线的类型。
第八个参数表示偏移量,如果传入(10,20),那绘制将从图像的(10,20)处开始。
//图像的轮廓检测 #include <opencv2/opencv.hpp> using namespace std; #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") int main( int argc, char** argv ) { const char *pstrWindowsSrcTitle = "原图"; const char *pstrWindowsOutLineTitle = "轮廓图"; const int IMAGE_WIDTH = 400; const int IMAGE_HEIGHT = 200; // 创建图像 IplImage *pSrcImage = cvCreateImage(cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U, 3); // 填充成白色 cvRectangle(pSrcImage, cvPoint(0, 0), cvPoint(pSrcImage->width, pSrcImage->height), CV_RGB(255, 255, 255), CV_FILLED); // 画圆 CvPoint ptCircleCenter = cvPoint(IMAGE_WIDTH / 4, IMAGE_HEIGHT / 2); int nRadius = 80; cvCircle(pSrcImage, ptCircleCenter, nRadius, CV_RGB(255, 255, 0), CV_FILLED); ptCircleCenter = cvPoint(IMAGE_WIDTH / 4, IMAGE_HEIGHT / 2); nRadius = 30; cvCircle(pSrcImage, ptCircleCenter, nRadius, CV_RGB(255, 255, 255), CV_FILLED); // 画矩形 CvPoint ptLeftTop = cvPoint(IMAGE_WIDTH / 2 + 20, 20); CvPoint ptRightBottom = cvPoint(IMAGE_WIDTH - 20, IMAGE_HEIGHT - 20); cvRectangle(pSrcImage, ptLeftTop, ptRightBottom, CV_RGB(0, 255, 255), CV_FILLED); ptLeftTop = cvPoint(IMAGE_WIDTH / 2 + 60, 40); ptRightBottom = cvPoint(IMAGE_WIDTH - 60, IMAGE_HEIGHT - 40); cvRectangle(pSrcImage, ptLeftTop, ptRightBottom, CV_RGB(255, 255, 255), CV_FILLED); // 显示原图 cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsSrcTitle, pSrcImage); // 转为灰度图 IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1); cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY); // 转为二值图 IplImage *pBinaryImage = cvCreateImage(cvGetSize(pGrayImage), IPL_DEPTH_8U, 1); cvThreshold(pGrayImage, pBinaryImage, 250, 255, CV_THRESH_BINARY); // 检索轮廓并返回检测到的轮廓的个数 CvMemStorage *pcvMStorage = cvCreateMemStorage(); CvSeq *pcvSeq = NULL; cvFindContours(pBinaryImage, pcvMStorage, &pcvSeq, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0)); // 画轮廓图 IplImage *pOutlineImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 3); int nLevels = 5; // 填充成白色 cvRectangle(pOutlineImage, cvPoint(0, 0), cvPoint(pOutlineImage->width, pOutlineImage->height), CV_RGB(255, 255, 255), CV_FILLED); cvDrawContours(pOutlineImage, pcvSeq, CV_RGB(255,0,0), CV_RGB(0,255,0), nLevels, 2); // 显示轮廓图 cvNamedWindow(pstrWindowsOutLineTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsOutLineTitle, pOutlineImage); cvWaitKey(0); cvReleaseMemStorage(&pcvMStorage); cvDestroyWindow(pstrWindowsSrcTitle); cvDestroyWindow(pstrWindowsOutLineTitle); cvReleaseImage(&pSrcImage); cvReleaseImage(&pGrayImage); cvReleaseImage(&pBinaryImage); cvReleaseImage(&pOutlineImage); return 0; }
//图像的轮廓检测 #include <opencv2/opencv.hpp> using namespace std; #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") IplImage *g_pGrayImage = NULL; const char *pstrWindowsBinaryTitle = "二值图"; const char *pstrWindowsOutLineTitle = "轮廓图"; CvSeq *g_pcvSeq = NULL; void on_trackbar(int pos) { // 转为二值图 IplImage *pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1); cvThreshold(g_pGrayImage, pBinaryImage, pos, 255, CV_THRESH_BINARY); // 显示二值图 cvShowImage(pstrWindowsBinaryTitle, pBinaryImage); CvMemStorage* cvMStorage = cvCreateMemStorage(); // 检索轮廓并返回检测到的轮廓的个数 cvFindContours(pBinaryImage,cvMStorage, &g_pcvSeq); IplImage *pOutlineImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 3); int _levels = 5; cvZero(pOutlineImage); cvDrawContours(pOutlineImage, g_pcvSeq, CV_RGB(255,0,0), CV_RGB(0,255,0), _levels); cvShowImage(pstrWindowsOutLineTitle, pOutlineImage); cvReleaseMemStorage(&cvMStorage); cvReleaseImage(&pBinaryImage); cvReleaseImage(&pOutlineImage); } int main( int argc, char** argv ) { const char *pstrWindowsSrcTitle = "原图(http://blog.csdn.net/MoreWindows)"; const char *pstrWindowsToolBarName = "二值化"; // 从文件中加载原图 IplImage *pSrcImage = cvLoadImage("C:\\xy.jpg", CV_LOAD_IMAGE_UNCHANGED); // 显示原图 cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsSrcTitle, pSrcImage); // 转为灰度图 g_pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1); cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY); // 创建二值图和轮廓图窗口 cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(pstrWindowsOutLineTitle, CV_WINDOW_AUTOSIZE); // 滑动条 int nThreshold = 0; cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar); on_trackbar(1); cvWaitKey(0); cvDestroyWindow(pstrWindowsSrcTitle); cvDestroyWindow(pstrWindowsBinaryTitle); cvDestroyWindow(pstrWindowsOutLineTitle); cvReleaseImage(&pSrcImage); cvReleaseImage(&g_pGrayImage); return 0; }
相关文章推荐
- OpenCV学习笔记: 快速入门例程
- OpenCV学习笔记之二――基于Haar-like特征的层叠推进分类器快速
- Python核心编程(第二版)学习笔记01 【第2章 快速入门】
- Qt快速入门学习笔记(基础篇)
- Sass学习笔记 — 2. 快速入门
- lua学习笔记之三(C/C++程序员的Lua快速入门[高阶话题])
- Python学习笔记(一):基础语法、变量类型、运算符(快速入门篇)
- Spring学习笔记(3)——快速入门
- python opencv入门(学习笔记no.2)-视频的读入读出
- opencv3学习笔记(一)——opencv入门
- java学习笔记之java如何快速入门
- Qt快速入门学习笔记(画图篇)
- Jpa快速开发学习笔记(入门)
- webpack 学习笔记 02 快速入门
- Python学习笔记(二):语句、数据类型(快速入门篇)
- Spring学习笔记(3)----------Spring快速入门
- OpenCV学习笔记一 例程
- 【OpenCV学习笔记】二、OpenCV例程赏析
- 韩顺平PHP学习视频笔记整理024php快速入门 bs和cs介绍
- opencv 学习笔记-入门(21)之三线性插值-hog(二)