cvFindContours/findContours提取轮廓
2014-07-25 17:08
183 查看
opencv在提取轮廓时,C/C++有两种方式,有些许不同,结合查找的资料和补充,做个小笔记;
功能,提取满足一定面积阈值和宽高比例的轮廓;
主函数
API实现
cvFindContours形式
findContours形式
之后
over!
功能,提取满足一定面积阈值和宽高比例的轮廓;
主函数
static int getContoursByC(char* Imgname, double minarea = 100, double whRatio = 1); static int getContoursByCplus(char* Imgname, double minarea=0, double whRatio=1); int main() { char* filename = new char[50]; strcpy(filename, "../image/rl_4.jpg"); getContoursByCplus(filename); delete[] filename; return 0; }
API实现
cvFindContours形式
/*采用cvFindContours提取轮廓,并过滤掉小面积轮廓,最后将轮廓保存*/ static int getContoursByC(char* Imgname, double minarea, double whRatio) { IplImage* src = cvLoadImage(Imgname, CV_LOAD_IMAGE_GRAYSCALE); if (!src) { printf("read data error!\n"); return -1; } IplImage* dst = cvCreateImage(cvGetSize(src), 8, 3); //the parm. for cvFindContours CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contour = 0; double maxarea = 0; //for display cvNamedWindow("Source", CV_WINDOW_NORMAL); cvShowImage("Source", src); //二值化 cvThreshold(src, src, 120, 255, CV_THRESH_BINARY); //提取轮廓 cvFindContours(src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); cvZero(dst);//清空数组 /*CvSeq* _contour为了保存轮廓的首指针位置,因为随后contour将用来迭代*/ CvSeq* _contour = contour; int maxAreaIdx = -1, iteratorIdx = 0;//n为面积最大轮廓索引,m为迭代索引 for (int iteratorIdx = 0; contour != 0; contour = contour->h_next, iteratorIdx++/*更新迭代索引*/) { double tmparea = fabs(cvContourArea(contour)); if (tmparea > maxarea) { maxarea = tmparea; maxAreaIdx = iteratorIdx; continue; } if (tmparea < minarea) { //删除面积小于设定值的轮廓 cvSeqRemove(contour, 0); continue; } CvRect aRect = cvBoundingRect(contour, 0); if ((aRect.width / aRect.height)<whRatio) { //删除宽高比例小于设定值的轮廓 cvSeqRemove(contour, 0); continue; } //CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );//创建一个色彩值 //CvScalar color = CV_RGB(0, 255, 255); //max_level 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。 //如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。 //如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。 //cvDrawContours(dst, contour, color, color, -1, 1, 8);//绘制外部和内部的轮廓 } contour = _contour; /*int k=0;*/ //统计剩余轮廓,并画出最大面积的轮廓 int count = 0; for (; contour != 0; contour = contour->h_next) { count++; double tmparea = fabs(cvContourArea(contour)); if (tmparea == maxarea /*k==n*/) { CvScalar color = CV_RGB(255, 0, 0); cvDrawContours(dst, contour, color, color, -1, 1, 8); } /*k++;*/ } printf("The total number of contours is:%d", count); cvNamedWindow("Components", CV_WINDOW_NORMAL); cvShowImage("Components", dst); cvSaveImage("dst.jpg", dst); //roateProcess(dst); cvWaitKey(0); //销毁窗口和图像存储 cvDestroyWindow("Source"); cvReleaseImage(&src); cvDestroyWindow("Components"); cvReleaseImage(&dst); return 0; }
findContours形式
static int getContoursByCplus(char* Imgname, double minarea, double whRatio) { cv::Mat src, dst, canny_output; /// Load source image and convert it to gray src = imread(Imgname, 0); if (!src.data) { std::cout << "read data error!" << std::endl; return -1; } blur(src, src, Size(3, 3)); //the pram. for findContours, vector<vector<Point> > contours; vector<Vec4i> hierarchy; /// Detect edges using canny Canny(src, canny_output, 80, 255, 3); /// Find contours findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); //CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE double maxarea = 0; int maxAreaIdx = 0; for (int i = 0; i<contours.size(); i++) { double tmparea = fabs(contourArea(contours[i])); if (tmparea>maxarea) { maxarea = tmparea; maxAreaIdx = i; continue; } if (tmparea < minarea) { //删除面积小于设定值的轮廓 contours.erase(contours.begin() + i); std::wcout << "delete a small area" << std::endl; continue; } //计算轮廓的直径宽高 Rect aRect =boundingRect(contours[i]); if ((aRect.width / aRect.height)<whRatio) { //删除宽高比例小于设定值的轮廓 contours.erase(contours.begin() + i); std::wcout << "delete a unnomalRatio area" << std::endl; continue; } } /// Draw contours,彩色轮廓 dst= Mat::zeros(canny_output.size(), CV_8UC3); for (int i = 0; i< contours.size(); i++) { //随机颜色 Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point()); } // Create Window char* source_window = "countors"; namedWindow(source_window, CV_WINDOW_NORMAL); imshow(source_window, dst); cv:; waitKey(0); return 0; }
之后
over!
相关文章推荐
- 提取轮廓在OpenCV里有一个函数 cvFindContours
- cvFindContours/findContours提取轮廓
- cvFindContours轮廓提取解析_OpenCV
- 提取轮廓函数 cvFindContours ---OpenCV
- opencv序列结构CvSeq和轮廓提取cvFindContours的简单运用
- cvFindContours 提取外轮廓
- [转]opencv使用cvFindContours提取联通域
- cvFindContours之轮廓个数
- OpenCV中findContours轮廓提取一个边缘只对应的一个轮廓
- opencv使用cvFindContours提取联通域
- cvFindContours之轮廓个数
- OpenCV示例学习笔记(1)-contours2.cpp-通过findContours 函数实现轮廓提取
- opencv查找轮廓---cvFindContours && cvDrawCountours 用法及例子
- 图像轮廓查找与绘制——cv::findContours()与cv::drawContours()详解
- OpenCV轮廓、边缘、边界的相关函数cv::findContours()等
- cvFindContours && cvDrawContours 的应用2-----图像内轮廓填充
- 轮廓提取findContours和绘制drawContours
- 图像的轮廓检测cvFindContours
- Opencv通过cvFindContours找到的轮廓图时暗时亮
- OpenCV3.0 Examples学习笔记(1)-contours2.cpp-通过findContours 函数实现轮廓提取