Ask Your Question

filter2D Filter out crosses

asked 2018-03-07 18:46:24 -0500

try_automation gravatar image


I am a bit new to openCV and have been using it pretty successfully for cleaning up and rotating images before OCR. However I have come across a problem with some documents. If you see the attached image below you will see that if you zoom into the image there are all these little plus looking things in white. I was wondering if someone could point me in the right direction for removing them. I tried something like below. However I believe I am a off in what I am trying to do. If this is in the right direction, could you point me to what would be a better value for my kernel. Or if this is totally off, what kind of method should I be using? Thank you! (note plus sign is 3x3 box)

`cv::Mat myPlusKernel = (cv::Mat_<float>(5, 5) << -0.025, -0.025, -0.025, -0.025, -0.025, -0.025, -0.025, 0.3, -0.025, -0.025, -0.025, 0.3, 0.3, 0.3, -0.025, -0.025, -0.025, 0.3, -0.025, -0.025, -0.025, -0.025, -0.025, -0.025, -0.025);

cv::filter2D(img1_pre, img1, -1, myPlusKernel, cv::Point(-1, -1), (0, 0), cv::BORDER_DEFAULT);
if (debug) {
    cv::namedWindow("CK", cv::WINDOW_AUTOSIZE); // Create a window for display.
    cv::imshow("CK", img1); // Show our image inside it.
    cv::imwrite("CK.jpg", img1);

image description

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2018-03-08 09:55:15 -0500

LBerger gravatar image

updated 2018-03-08 11:23:06 -0500

If cross size is constant (in your example 27X27) you can try template matching :

int main(void) {
Mat img = imread("croix.png", IMREAD_GRAYSCALE);
Mat cross(27, 27, CV_8UC1, Scalar(1));
Mat black(9, 9, CV_8UC1, Scalar(0));
Mat result;
black.copyTo(cross(Rect(0, 0, 9, 9)));
black.copyTo(cross(Rect(18, 0, 9, 9)));
black.copyTo(cross(Rect(0, 18, 9, 9)));
black.copyTo(cross(Rect(18, 18, 9, 9)));
Mat crossF, imgF;
img.convertTo(imgF, CV_32F);
cross.convertTo(crossF, CV_32F);
matchTemplate(imgF, crossF, result, CV_TM_CCORR_NORMED);

Mat plus = result>0.92;// why 0.92? try and test
Mat mask;
dilate(plus, mask, cross);
img = imread("croix.png", IMREAD_COLOR);
img(Rect(cross.cols/2, cross.rows / 2,plus.cols,plus.rows)).setTo(Vec3b(0, 0, 0), mask);
imshow("plus", img);

Result :

image description

edit flag offensive delete link more


Thank you, I think my example is messed up because it's a screenshot of a section, the true crosses are 3x3 boxes. So for your code would I want to divide all your numbers by 9?

try_automation gravatar imagetry_automation ( 2018-03-08 11:24:27 -0500 )edit

YES that worked!!! Thank you very very very much!!!

try_automation gravatar imagetry_automation ( 2018-03-08 11:26:20 -0500 )edit

answered 2018-03-07 18:59:30 -0500

Tetragramm gravatar image

If you use a 3x3 opening operation with a box kernel, that should do it. It might do things like merge really nearby letters but hopefully your OCR can handle that.

edit flag offensive delete link more


Thank you! That helped a lot, however it does like you say make the text run together. Do you know if there is by any chance a method in Open CV that will find that pattern (the white cross) and replace it with a new pattern (black cross)?

try_automation gravatar imagetry_automation ( 2018-03-08 09:55:41 -0500 )edit

Question Tools

1 follower


Asked: 2018-03-07 18:46:24 -0500

Seen: 363 times

Last updated: Mar 08 '18