OpenCV:曲线的检测与提取-0

 时间:2024-10-21 13:16:33

1、基本思想:给出一个带有曲线像素宽度为1的二值图像;①遍历图像像素,找到第一个白色的点;②在此点的八邻域内找到下一个白色的点;③将找到的点的灰度值置为0;保存找到点的坐标;④八邻域内没有找到白色点,则表示一端搜索完成;原图如下:

OpenCV:曲线的检测与提取-0

2、【注】:①第一个找到的点不一定是曲线的端点,因此应该分别向两边寻找相邻的点;②在搜寻相邻像素点时,会首先搜寻此点与上一个点相邻像素相对的位置;这样可以减少寻找的次数,而且当有相交的曲线时,能连接到我们一般认为的曲线。

OpenCV:曲线的检测与提取-0

3、程序如下://寻找二值图像上的第一个点//maskImg二值图像,标记//outPoint输出查找的点bool findFirstPoint(Mat &maskImg, Point &outPoint){ bool success = false; for (int i = 0; i < maskImg.rows; i++) { unsigned char *pData = (unsigned char*)(maskImg.data+i*maskImg.step); for (int j = 0; j < maskImg.cols; j++) { if (pData[j] == 255)//找到第一个白色的点 { success = true; outPoint.x = j; outPoint.y = i; pData[j] = 0;//将此点像素设为0 break; } } if (success) break; } return success;}

OpenCV:曲线的检测与提取-0

4、//八邻域中寻找曲线上某个点的下一个点//neiPoint八邻域点//currPt当前点bool findNextPoint(vector<Point> &neiPt, Mat &image, Point currPt, int currFlag, Point& outPt, int &outFlag){ int i = currFlag;//0,6 int count = 1; bool success = false; while (count <= 7) { Point tpPt = currPt + neiPt[i];//邻域像素点 if (tpPt.x > 0 && tpPt.y > 0 && tpPt.x < image.cols && tpPt.y < image.rows)//在图像内部 { if( ((unsigned char*)(image.data+tpPt.y*image.step))[tpPt.x]==255 ) { outPt = tpPt; outFlag = i; success = true; ((unsigned char*)(image.data+tpPt.y*image.step))[tpPt.x]=0; break;//跳出循环 } } if (count % 2)//奇数 { i += count; if (i > 7) { i -= 8; } } else { i += -count; if (i < 0) { i += 8; } } count++; } return success;}

OpenCV:曲线的检测与提取-0

5、//寻找曲线 :void findLines(Mat &binaryImg, vector<deque<Point>> &outLines){ //八邻域 vector<Point> neighborPtVec; neighborPtVec.push_back(Point(-1,-1)); neighborPtVec.push_back(Point(0,-1)); neighborPtVec.push_back(Point(1,-1)); neighborPtVec.push_back(Point(1,0)); neighborPtVec.push_back(Point(1,1)); neighborPtVec.push_back(Point(0,1)); neighborPtVec.push_back(Point(-1,1)); neighborPtVec.push_back(Point(-1,0)); Point firstPt; while (findFirstPoint(binaryImg, firstPt)) { deque<Point> line;//点的队列 line.push_back(firstPt);//存储第一个点 //由于第一个点不一定是线段的起始位置, //因此两个方向都要查找 Point currPt = firstPt;//当前点 int currFlag = 0;//标志 Point nextPt;//下一个点 int nextFlag;//下一点的标志 while (findNextPoint(neighborPtVec, binaryImg, currPt, currFlag, nextPt, nextFlag))//一端 { line.push_back(nextPt);//压入队列 currPt = nextPt; currFlag = nextFlag; } //找另一端 currPt = firstPt; currFlag = 0; while (findNextPoint(neighborPtVec, binaryImg, currPt, currFlag, nextPt, nextFlag)) { line.push_front(nextPt); currPt = nextPt; currFlag = nextFlag;//邻域与中心像素的位置 } if (line.size() > 10) { outLines.push_back(line); } }}

OpenCV:曲线的检测与提取-0

6、//主函数main://用deque<Point> 描述曲线//随机取色画曲线Scalar random_color(RNG& _rng){ int icolor = (unsigned)_rng; return Scalar(icolor & 0xFF, (icolor >> 8) & 0xFF, (icolor >> 16) & 0xFF);}int main(){ Mat binaryImg = imread("1.jpg",0); vector<deque<Point>> lines; findLines(binaryImg, lines); cout << lines.size() << endl; //draw lines Mat draw_img; cvtColor(binaryImg,draw_img,CV_GRAY2BGR); RNG rng(123); Scalar color; for (int i = 0; i < lines.size(); i++) { color = random_color(rng); for (int j = 0; j < lines[i].size(); j++) { draw_img.at<Vec3b>(lines[i][j]) = Vec3b(color[0], color[1], color[2]); } } imshow("draw_img", draw_img); imwrite("draw_img.jpg", draw_img); waitKey(0); return 0;}

OpenCV:曲线的检测与提取-0
OpenCV:曲线的检测与提取-0
  • 基于Fluent数据Tecplot软件如何画XYline(1/5)
  • HyperMesh与ANSYS过盈接触联合仿真(1)
  • 小米手机计算器怎么计算个税?
  • area对象的属性coords如何使用?
  • matlab特殊字符的标记
  • 热门搜索
    预防疾病手抄报 关于疫情的手抄报 关于法制的手抄报 足球手抄报图片大全 关于水的手抄报 关于消防的手抄报 放飞梦想手抄报 长征手抄报 防溺水手抄报资料 创建文明校园手抄报