Reputation: 921
I am trying to extract points from image that makes up some sign.
First of all I am applying adaptive threshold:
Then I try to detect blobs and ignore all that don't make up the sign with measuring distances and blobs radius.
But that doesn't do it precisly (different original image) and many artefacts are detected. I tried all variations of parameters, but none fits for :
Is there some better way to it?
The picture comes from camera and I am trying to detect missing dots in sign. If dots are missing, they missing from the bottom and affect entire row (so they affect total height of sign). Now I am creating template with no missing dots and compare it to actual image every few frames, but that doesn't work, because the error that missing dots create is smaller than error between frames.
Any ideas for better approach to this problem?
Upvotes: 1
Views: 354
Reputation: 394
Result
I have implemented the code as per the direction @FiReTiTi. Please check out.!!
#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();
}
Upvotes: -1
Reputation: 5898
Here is what I've just tested and it gives good results:
It gives a better result than an automatic thresholding.
[EDIT] here is a result, but with just an opening and a white top-hat of size 13: result
Upvotes: 0
Reputation: 1670
I dealt with a similar problem, my approach was longer, but it gave more parameters to tune (a benefit as much as it can be a curse) - anyways:
Play around with the initial image processing so that it errs on the side of giving (slightly) more candidates contours than you should - then filter according to the characteristics of your targets vs. false positives.
If you haven't used contours and moment analysis before, now is the time to read up on it...
In my case I implemented:
Upvotes: 2