OpenCV中利用CvHoughCircles提取图像中的圆,从而可以得到圆心坐标

OpenCV中利用CvHoughCircles提取图像中的圆,从而可以得到圆心坐标,第1张

其实吧,这种问题完全可以自己解决。

如果我有这个问题,我会

1 去opencv官网 看这个函数的解释

circles – Output vector of found circles Each vector is encoded as a 3-element floating-(x,y,radius) point vector 这个点是x和y

2 用画圆的函数 cvCircle画一个

cvCircle( img_circle, cvPoint(cvRound(p_c[0]),cvRound(p_c[1])), p_c[2], , CV_RGB(255,255,0), -1, 8, 0 );

结果你看,cvPoint里的参数是 p0和p1 这不就说是正是x y坐标吗?

希望你能早日解决问题并且学到自己解决问题的能力。

再见~

By 风之风信子

最简单的方法是,如果大小固定,你跟踪一下在cview类显示的左上角和右下角的位置设为(x1,y1),(x2,y2)(鼠标点那两个点就行)

通过LBUTTONDOWN得到当前鼠标位置设为(x,y)

真实像素值为wh

J=(x-x1)w/(x2-x1)

I=(y-y1)H/(y2-y1)

w和h你要想明白,容易搞混

Hi Opencv 带有这样一个函数cvFindcontours,若输入为二值图像,则能够返回响应的边缘线的坐标。当然还有其他方法能够解决你的问题,比如你可以使用穷举的方法将坐标点列出,希望能够帮到你。关于cvFindcontours函数你可以参考 >

今天我们将一起探究如何使用OpenCV和Python从图像中提取感兴趣区域(ROI)。

在之间的文章中,我们完成了图像边缘提取,例如从台球桌中提取桌边。使用了简单的OpenCV函数即可完成这项任务,例如inRange、findContours、boundingRect、minAreaRect、 minEnclosingCircle、circle、HoughLines、line等,都可以。

今天我们的任务是从包含患者大脑活动快照的图像中提取所需的片段。之后可以将该提取的过程应用于其他程序中,例如诊断健康与否的机器学习模型。

因此,让我们从查看输入图像开始。这是由神经科学领域的医疗仪器生成的典型报告,该仪器使用传感器检测来自患者大脑的信号并将其显示为彩色地图。通常,有四张,所有都描绘了某个特征并一起分析以进行诊断。

本练习的目标图像包含四个大脑图

从上面的图像中,我们只想提取与四个地图(头部扫描)相对应的区域,而将其他所有内容都排除在外。因此,让我们开始吧。

第一步是检测我们要提取的片段的边缘。这是一个多步骤过程,如下所述:

1 使用“ cvtColor()”将RGB图像转换为灰度

2 通过应用模糊函数“ GaussianBlur()”来消除灰度图像中的噪声

3 最后将“ Canny()”函数应用于模糊图像以获得边缘

边缘检测过程的输出如下所示:

使用Canny算法的边缘检测输出

请注意,尽管已识别出脑段,但仍有许多不需要的边缘需要消除,并且某些边缘之间有间隙需要封闭。

解决这个问题的一种常用方法是形态转换,它涉及在图像上使用一系列的扩张和腐蚀来去除不需要的边缘和闭合间隙。

我们在多次迭代中使用OpenCV函数“ dilate()”和“ erode()”来获得如下输出。

使用OpenCV对边缘进行了一些增强

如我们看到的那样,边缘现在已经完成并且比以前光滑得多。

现在,我们可以使用OpenCV函数“ findContours()”提取该图像中的轮廓,并仅选择具有以下属性的轮廓:

1 几何形状是圆形或椭圆形

2 面积大于某个阈值(在此示例中,值7000可以正常工作)。

对于第一部分,我们将使用OpenCV的“ boundingRect()”检测每个轮廓的边界矩形,并检查纵横比(高宽比)是否接近1。

现在我们的任务已经完成,但还需要进行一些微调。

通常情况是在一个片段上检测到多个重叠的轮廓,而我们只对一个感兴趣。

使用非极大抑制可以解决此问题,即我们查看所有重叠的轮廓,然后选择面积最大的轮廓作为最终候选轮廓。逻辑非常简单,因此我们不需要任何内置的OpenCV或Python函数。

另一个重要的逻辑是分别识别四个部分,即左上,右上,左下和右下。

这也非常简单,涉及识别图像中心坐标以及每个检测到的片段的质心。对段轮廓进行质心检测需要在轮廓上应用OpenCV “ moments()”函数,然后使用以下公式计算中心 X,Y坐标:

center_x,center_y =(int(M [“ m10”] / M [” m00”]),int(M [“ m01”] / M [“ m00”]))

将线段质心坐标与图像中心坐标进行比较,可以将四个线段分别放置在各自的位置。

现在我们已经确定了四个部分,我们需要构建图像蒙版,这将使我们能够从原始图像中提取所需的特征。

我们将使用OpenCV函数“ drawContours()”,将颜色用作白色(R,G,B = 255,2555,255),将厚度用作FILLED(-1)在黑色背景上绘制所有四个线段轮廓。结果如下所示:

用于提取我们的ROI的蒙版

在原始图像上应用此蒙版可以在我们选择的背景(例如黑色或白色)上为我们提供所需的分段。

对于黑色背景,我们创建一个黑色画布,然后使用OpenCV函数“ bitwise_and()”以及先前获得的蒙版在其上进行绘制。

在黑色背景上提取的ROI

对于白色背景,我们首先创建一个白色画布,然后通过使用OpenCV函数“ drawContours()”绘制轮廓为黑色(R,G,B = 0,0,0)且厚度为FILLED的轮廓,如下所示创建颜色反转的蒙版(-1)。

用于ROI提取的备用倒置掩模(图像源作者)

然后,我们使用OpenCV “ add()”函数将此反向蒙版添加到先前获得的黑色背景中,并获得相同的结果,但使用白色背景。

在白色背景上提取的ROI

到此为止,我们总结了几种方法,可以轻松地从图像中提取感兴趣区域。

应当注意,在具有变化的复杂度的其他图像的情况下,上面使用的方法可以进行修改。

First we must know the structure of IplImage:

IPL image:

IplImage

  |-- int  nChannels;     // Number of color channels (1,2,3,4)

  |-- int  depth;         // Pixel depth in bits:

  |                       //   IPL_DEPTH_8U, IPL_DEPTH_8S,

  |                       //   IPL_DEPTH_16U,IPL_DEPTH_16S,

  |                       //   IPL_DEPTH_32S,IPL_DEPTH_32F,

  |                       //   IPL_DEPTH_64F

  |-- int  width;         // image width in pixels

  |-- int  height;        // image height in pixels

  |-- char imageData;    // pointer to aligned image data

  |                       // Note that color images are stored in BGR order

  |-- int  dataOrder;     // 0 - interleaved color channels,

  |                       // 1 - separate color channels

  |                       // cvCreateImage can only create interleaved images

  |-- int  origin;        // 0 - top-left origin,

  |                       // 1 - bottom-left origin (Windows bitmaps style)

  |-- int  widthStep;     // size of aligned image row in bytes

  |-- int  imageSize;     // image data size in bytes = heightwidthStep

  |-- struct _IplROI roi;// image ROI when not NULL specifies image

  |                       // region  to be processed

  |-- char imageDataOrigin; // pointer to the unaligned origin of image data

  |                          // (needed for correct image deallocation)

  |

  |-- int  align;         // Alignment of image rows: 4 or 8 byte alignment

  |                       // OpenCV ignores this and uses widthStep instead

  |-- char colorModel[4]; // Color model - ignored by OpenCV

//------------------------------------------------------------------------------int main(int argc, char argv[])

{

    IplImage img=cvLoadImage("c://fruitfsbmp",1);

    CvScalar s;

    for(int i=0;i<img->height;i++){

        for(int j=0;j<img->width;j++){

        s=cvGet2D(img,i,j); // get the (i,j) pixel value

        printf("B=%f, G=%f, R=%f ",sval[0],sval[1],sval[2]);

        sval[0]=111;

        sval[1]=111;

        sval[2]=111;

        cvSet2D(img,i,j,s);//set the (i,j) pixel value

        }

    }

    cvNamedWindow("Image",1);

    cvShowImage("Image",img);

    cvWaitKey(0); //等待按键

    cvDestroyWindow( "Image" );//销毁窗口

    cvReleaseImage( &img ); //释放图像

    return 0;

}

以上就是关于OpenCV中利用CvHoughCircles提取图像中的圆,从而可以得到圆心坐标全部的内容,包括:OpenCV中利用CvHoughCircles提取图像中的圆,从而可以得到圆心坐标、在MFC中的单文档中通过OPENCV的IplImage把图像显示出来后,在View类中得到鼠标坐标(x,y)。、openCV android 获取描绘物体轮廓的点坐标等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9723947.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存