opencv形态学应用之边界提取与跟踪
来源:互联网 发布:ggplot python 编辑:程序博客网 时间:2024/05/20 11:51
边界提取:根据之前的博客就是用原图减去腐蚀后的图像;
边界跟踪:按照某种扫描规则找到目标边界上的像素直到回到原点;
本程序中,我采用从左到右从上到下的顺序查找边界,如下图所示,分别从左下、下、右下右、右上、上、左上、左方向搜索边界点,当搜索到原点时,边界搜索结束。
当图像中有多个连通域时,显然这种方法就不适用,所以改进的方法是:每搜索完一个边界,将改连通域设置为背景颜色(如:0),然后继续搜索
#include<opencv2\opencv.hpp>#include<iostream>using namespace std;using namespace cv;void erode(const Mat _src, Mat& dst, int se[3][3]);void dilate(const Mat _src, Mat& dst, int se[3][3]);/**************************************************功能:边界跟踪参数:src-二值图像***************************************************/void traceBoundary(Mat src, Mat& dst){//起始边界点和当前边界点Point ptStart;Point ptCur;//搜索方向数组{左下,下,右下,右,右上,上,左上,左}int Direction[8][2] = { { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 } };int nCurDirect = 0;//当前探查的方向//搜索开始,区别ptCur==ptStart的两种情况(一种开始,一种结束)bool bAtStartPt;//算法不处理边界上的点,将图像的四周设置为白//for (int i = 0; i < src.rows; i++)//{//dst.at<uchar>(i, 0) = 255;//dst.at<uchar>(i, src.rows - 1) = 255;//}//for (int j = 0; j < src.cols; j++)//{//dst.at<uchar>(0, j) = 255;//dst.at<uchar>(src.rows - 1, j) = 255;//}int xPos, yPos;//逐行扫描for (int i = 0; i < src.rows; i++){for (int j = 0; j < src.cols; j++){if (src.at<uchar>(i, j) > 0){ptStart.x = j;ptStart.y = i;ptCur = ptStart;bAtStartPt = true;while ((ptCur.x != ptStart.x) || (ptCur.y != ptStart.y) || bAtStartPt){bAtStartPt = false;//下一个探查位置xPos = ptCur.x + Direction[nCurDirect][0];yPos = ptCur.y + Direction[nCurDirect][1];int nSearchTimes = 1;while (src.at<uchar>(yPos, xPos) ==0){nCurDirect++;//逆时针旋转45度if (nCurDirect >= 8)nCurDirect -= 8;xPos = ptCur.x + Direction[nCurDirect][0];yPos = ptCur.y + Direction[nCurDirect][1];//8领域中都没有边界点,说明是孤立点if (++nSearchTimes >= 8){xPos = ptCur.x;yPos = ptCur.y;break;}}//找到下一个边界点ptCur.x = xPos;ptCur.y = yPos;//在新像上标记边界dst.at<uchar>(ptCur.y, ptCur.x) = 255;/***********此处可以定义vector存储提取的边界点************///将当前探查方向顺时针回转90度作为下一次的探查初始方向nCurDirect -= 2;if (nCurDirect < 0){nCurDirect += 8;}}return;}//当存在多个边界时,在此处添加相应代码,并删除return(每跟踪完一个边界,删除相应的区域)}}}int main(){//读取二值图像(此步可以忽略)Mat src = imread("test1.jpg", 0);Mat src_binary;threshold(src, src_binary, 250, 255, THRESH_BINARY);imshow("原始图像", src_binary);//创建模板int se[3][3] = { { -1, 1, -1 }, { 1, 1, 1 }, { 1, 1, 1 } };//边界提取(原图-腐蚀后的图像)Mat dstImg;erode(src_binary, dstImg, se);dstImg = src_binary - dstImg;imshow("边界提取后的图像", dstImg);//边界跟踪Mat BoundaryImg = Mat::zeros(src_binary.size(), src_binary.type());traceBoundary(dstImg, BoundaryImg);imshow("边界图像", BoundaryImg);waitKey(0);return 0;}
原始图像:
边界提取的结果:
边界跟踪后的结果:
阅读全文
2 0
- opencv形态学应用之边界提取与跟踪
- opencv形态学应用之连通域提取
- 边界提取与跟踪
- OpenCV--提取水平与垂直线(形态学操作应用)
- 形态学边界提取
- opencv形态学应用之区域填充
- 【OpenCV】音符提取(形态学实例)
- OPENCV之形态学处理
- opencv之形态学操作
- opencv之形态学重建
- 图像处理算法基础(七)---形态学边界提取
- 形态学重建的应用1——去除与图像边界连通的目标
- 图像处理之边界跟踪
- opencv 连通区域边界坐标提取
- OpenCV之图像形态学运算
- OpenCV学习之形态学操作
- OpenCV学习之形态学操作
- 二值图像--形态学处理4 击中,边界提取,孔洞填充,连通分量提取,凸壳,细化,骨架,形态学重建
- mysql copy to tmp on disk
- touch事件中的touches、targetTouches和changedTouches详解
- oracle RAC 11g更改ASM磁盘路径
- ROS编程示例---输出消息
- 20170606组队赛比赛总结
- opencv形态学应用之边界提取与跟踪
- OOP Unit03 对象内存管理 、 继承的意义(上)
- Maven仓库私服索引配置(详细)
- 第三章 Vuser发生器
- JavaScript JSON
- 我的第一篇博客
- AlertDialog无法铺满
- 《软件工程(C编码实践篇)》
- 移动端屏幕适配——中篇