检测图像中的点并进行比较
Detect points in image and compare them
我正在尝试从构成某些符号的图像中提取点。
首先我要应用自适应阈值:
然后我尝试检测斑点并忽略所有不构成标志的测量距离和斑点半径。
但这并不能准确地做到这一点(不同的原始图像)并且检测到许多人工制品。我尝试了所有参数变体,但 none 适合 :
有没有更好的方法?
图片来自相机,我正在尝试检测标志中缺失的点。如果缺少点,它们会从底部丢失并影响整行(因此它们会影响标志的总高度)。现在我正在创建没有遗漏点的模板,并每隔几帧将其与实际图像进行比较,但这不起作用,因为遗漏点造成的错误小于帧之间的错误。
关于更好地解决此问题的任何想法?
这是我刚刚测试过的,它给出了很好的结果:
- 以较小的结构元素半径开+闭以清洁一点图像
- 白色大礼帽,以便提取您的文字。
它给出了比自动阈值更好的结果。
[编辑] 这是一个结果,但只有一个开口和一顶尺寸为 13 的白色大礼帽:result
我处理了一个类似的问题,我的方法更长,但它提供了更多的参数来调整(一个好处,也可能是一个诅咒)- 无论如何:
- GaussianBlur(如果需要)
- Canny 过滤器
- Dilate(如果需要从 Canny 步骤关闭 'rings')
- 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();
}
我正在尝试从构成某些符号的图像中提取点。
首先我要应用自适应阈值:
然后我尝试检测斑点并忽略所有不构成标志的测量距离和斑点半径。
但这并不能准确地做到这一点(不同的原始图像)并且检测到许多人工制品。我尝试了所有参数变体,但 none 适合 :
有没有更好的方法?
图片来自相机,我正在尝试检测标志中缺失的点。如果缺少点,它们会从底部丢失并影响整行(因此它们会影响标志的总高度)。现在我正在创建没有遗漏点的模板,并每隔几帧将其与实际图像进行比较,但这不起作用,因为遗漏点造成的错误小于帧之间的错误。
关于更好地解决此问题的任何想法?
这是我刚刚测试过的,它给出了很好的结果:
- 以较小的结构元素半径开+闭以清洁一点图像
- 白色大礼帽,以便提取您的文字。
它给出了比自动阈值更好的结果。
[编辑] 这是一个结果,但只有一个开口和一顶尺寸为 13 的白色大礼帽:result
我处理了一个类似的问题,我的方法更长,但它提供了更多的参数来调整(一个好处,也可能是一个诅咒)- 无论如何:
- GaussianBlur(如果需要)
- Canny 过滤器
- Dilate(如果需要从 Canny 步骤关闭 'rings')
- findContours
尝试初始图像处理,使其错误地给出(略)多于您应有的候选轮廓 - 然后 根据目标的特征进行过滤与误报。
如果您之前没有使用过轮廓和力矩分析,现在是时候阅读它了...
在我的例子中,我实现了:
- A 'hierarchical' 基于等高线嵌套方式的过滤器 彼此。
- 一个 'morphological' 过滤器,用于寻找周长与面积之比接近理想圆的轮廓(这看起来与您的任务相关)。
结果
#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();
}