Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在opencv(c+;+;)中计算标记组件(二进制图像)之间的成对距离_C++_Opencv_Image Processing_Nearest Neighbor - Fatal编程技术网

C++ 如何在opencv(c+;+;)中计算标记组件(二进制图像)之间的成对距离

C++ 如何在opencv(c+;+;)中计算标记组件(二进制图像)之间的成对距离,c++,opencv,image-processing,nearest-neighbor,C++,Opencv,Image Processing,Nearest Neighbor,我有一个二进制图像,我在这里展示: 我使用opencv函数成功计算了这幅图像中所有白点的质心和统计信息:connectedComponentsWithStats,信息链接如下: 现在我必须计算所有白点之间的所有距离(成对)距离。我的问题是: 在opencv(c++)中,计算白点成对距离的最简单方法是什么?我在Python中读过k-近邻,但我不知道如何在C++中实现。计算完距离后,我必须将每两个比某个值更接近的点涂上颜色,例如,如果两个点比10像素更接近,则应将它们标记为红色(否则为绿色)最简

我有一个二进制图像,我在这里展示:

我使用opencv函数成功计算了这幅图像中所有白点的质心和统计信息:connectedComponentsWithStats,信息链接如下:

现在我必须计算所有白点之间的所有距离(成对)距离。我的问题是:


在opencv(c++)中,计算白点成对距离的最简单方法是什么?我在Python中读过k-近邻,但我不知道如何在C++中实现。计算完距离后,我必须将每两个比某个值更接近的点涂上颜色,例如,如果两个点比10像素更接近,则应将它们标记为红色(否则为绿色)

最简单的方法是自己使用两个循环和标准欧几里德距离公式。着色可以通过设置掩码来完成,其中的值与当前循环索引匹配

cv::Mat centorids, connectedComponentsLabels;
connectedComponentsWithStats(image, connectedComponentsLabels, stats, centroids, 8, CV_32S);
cv::Mat resultsImage = cv::Mat::zeros(connectedComponentsLabels.size(), CV_8UC3);
resultsImage.setTo(cv::Scalar(0, 255, 0), connectedComponentsLabels != 0); //precolor all points green, so that red coloring can override it
for (int i = 1; i < centroids.rows - 1; ++i)
{
    for (int j = i + 1; j < centroids.rows; ++j)
    {
        auto vec = cv::Point2d(centroids.at<double>(i, 0), centroids.at<double>(i, 1)) - 
                   cv::Point2d(centroids.at<double>(j, 0), centroids.at<double>(j, 1));
        double distSquared = vec.x * vec.x + vec.y * vec.y;
        if (distSquared > 100) //compare with 10 squared to avoid slow sqrt for distance
        {   //do the coloring red here
            resultsImage.setTo(cv::Scalar(255, 0, 0), connectedComponentsLabels == i);
            resultsImage.setTo(cv::Scalar(255, 0, 0), connectedComponentsLabels == j);
        }
    }
}
cv::材料中心、连接部件标签;
connectedComponentsWithStats(图像、connectedComponentsLabels、stats、质心、8、CV_32S);
cv::Mat resultsImage=cv::Mat::Zero(connectedComponentsLabels.size(),cv_8UC3);
resultsImage.setTo(cv::Scalar(0,255,0),connectedComponentsLabels!=0)//将所有点预着色为绿色,以便红色可以覆盖它
对于(int i=1;i100)//与10 squared比较,以避免距离的慢sqrt
{//这里是红色的吗
resultsImage.setTo(cv::Scalar(255,0,0),connectedComponentsLabels==i);
resultsImage.setTo(cv::Scalar(255,0,0),connectedComponentsLabels==j);
}
}
}

最简单的方法是在质心列表上做两个for循环,并计算每对质心之间的欧几里德距离。@您链接到的
connectedComponentsWithStats
的skoda23文档提到,
质心被设置到
Mat
中,其中第0列有x,第1列有y,每个组件都在自己的行中;尝试枚举
Mat
的行,而不是像I一样的
向量did@skoda23我的意思是主要输出:“labels”@skoda23请看我编辑过的答案,我想它现在应该可以正常工作了is@skoda23
connectedComponentsLabels
Mat
,它
connectedComponentsWithStats
在名为“labels”的参数中返回@第二行代码中的skoda23注释建议您调用
connectedComponentsWithStats
初始化第一行中声明的
Mat
s。是你干的吗?在我之前的评论中,“按原样”并不是指复制粘贴运行,而是指复制粘贴思考editabit运行