检测图像中的点并进行比较

Detect points in image and compare them

我正在尝试从构成某些符号的图像中提取点。

首先我要应用自适应阈值:

然后我尝试检测斑点并忽略所有不构成标志的测量距离和斑点半径。

但这并不能准确地做到这一点(不同的原始图像)并且检测到许多人工制品。我尝试了所有参数变体,但 none 适合 :

有没有更好的方法?

图片来自相机,我正在尝试检测标志中缺失的点。如果缺少点,它们会从底部丢失并影响整行(因此它们会影响标志的总高度)。现在我正在创建没有遗漏点的模板,并每隔几帧将其与实际图像进行比较,但这不起作用,因为遗漏点造成的错误小于帧之间的错误。

关于更好地解决此问题的任何想法?

这是我刚刚测试过的,它给出了很好的结果:

  1. 以较小的结构元素半径开+闭以清洁一点图像
  2. 白色大礼帽,以便提取您的文字。

它给出了比自动阈值更好的结果。

[编辑] 这是一个结果,但只有一个开口和一顶尺寸为 13 的白色大礼帽:result

我处理了一个类似的问题,我的方法更长,但它提供了更多的参数来调整(一个好处,也可能是一个诅咒)- 无论如何:

  1. GaussianBlur(如果需要)
  2. Canny 过滤器
  3. Dilate(如果需要从 Canny 步骤关闭 'rings')
  4. findContours

尝试初始图像处理,使其错误地给出(略)多于您应有的候选轮廓 - 然后 根据目标的特征进行过滤与误报。

如果您之前没有使用过轮廓和力矩分析,现在是时候阅读它了...

在我的例子中,我实现了:

  • A 'hierarchical' 基于等高线嵌套方式的过滤器 彼此。
  • 一个 'morphological' 过滤器,用于寻找周长与面积之比接近理想圆的轮廓(这看起来与您的任务相关)。

结果

我已经按照@FiReTiTi 的指导实现了代码。请检查。!!

#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;

int main(){
    Mat src = imread("7.png",1);
    imshow("src",src);
    src = src + Scalar (75,75,75);
    Mat erosion_dst;
    Mat dilation_dst;
    Mat dilation_dst1;
    int erosion_size = 8;   
cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS,
                      cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1), 
                      cv::Point(erosion_size, erosion_size) );
    erode( src, erosion_dst, element );
    erode(  erosion_dst, erosion_dst, element );
    erode(  erosion_dst, erosion_dst, element );
    dilate(erosion_dst, dilation_dst1, element );

    dilate(dilation_dst1, dilation_dst, element );
    dilate(dilation_dst, dilation_dst, element );
    dilate(dilation_dst, dilation_dst, element );
    erode( dilation_dst, dilation_dst, element );

    imshow("opening of image",dilation_dst);

    Mat topHat= src-dilation_dst;
    //topHat = topHat + 255;
    imshow("tophat image",topHat);

for(int i=0;i<topHat.rows;i++)
 {
  for(int j=0;j<topHat.cols;j++)
  {
   if(topHat.at<uchar>(i,j) > 2 )
    {
     //originalImage.at<Vec3b>(i,j) = 255;
        topHat.at<uchar>(i,j)=255;

        //   cout << i<<" " <<j<< endl; 
     }
   }
 }
//

imshow("Final image",topHat);
    waitKey();
}