OpenCV filter image - replace core with local maximum

Some details about my problem:

I am trying to implement an angular detector in openCV (another built-in algorithm: Canny, Harris, etc.).

I have a matrix filled with answer values. The biggest value of the answer is the greatest probability of detecting the angle.

I have a problem that several angles are found in the vicinity of the point (but there is only one). I need to reduce the number of falsely detected angles.

Exact problem:

I need to go through the matrix with the kernel, calculate the maximum value of each core, leave the maximum value, but the other values ​​in the kernel are zero.

Are there any built-in openCV features for this?

+4
source share
3 answers

Here's how I do it:

  • Create a kernel, it will determine the neighborhood of pixels.
  • Create a new image by expanding the image with this kernel. This extended image contains the maximum neighborhood value for each point.
  • Compare the equalities between the two arrays. Wherever they are equal, this is a valid maximum proximity and 255 set in the comparison array.
  • Multiply the comparison array and the original array (scaling accordingly).
  • This is your last array containing only the maximum values.

This is illustrated by these enlarged images:

9 pixels by 9 pixels of the original image:

enter image description here

After processing by a 5 by 5 pixel core, only local neighborhood maxima remain (i.e., the maximum values ​​are divided by more than 2 pixels from a pixel with a large value):

enter image description here

There is one caveat. If two close maxima have the same value, they will both be present in the final image.

Here is the Python code that does this, it is very easy to convert to C ++:

 import cv im = cv.LoadImage('fish2.png',cv.CV_LOAD_IMAGE_GRAYSCALE) maxed = cv.CreateImage((im.width, im.height), cv.IPL_DEPTH_8U, 1) comp = cv.CreateImage((im.width, im.height), cv.IPL_DEPTH_8U, 1) #Create a 5*5 kernel anchored at 2,2 kernel = cv.CreateStructuringElementEx(5, 5, 2, 2, cv.CV_SHAPE_RECT) cv.Dilate(im, maxed, element=kernel, iterations=1) cv.Cmp(im, maxed, comp, cv.CV_CMP_EQ) cv.Mul(im, comp, im, 1/255.0) cv.ShowImage("local max only", im) cv.WaitKey(0) 

I did not know until now, but this is what @sansuiso suggested in his / her answer.

This may be better illustrated by this image before:

enter image description here

after processing with a 5 by 5 core:

enter image description here

solid regions are determined by the values ​​of common local maxima.

+14
source

I would suggest an original two-step procedure (more efficient approaches may exist) that use the built-in opencv functions:

  • Step 1: morphological expansion with a square core (appropriate to your surroundings). This step gives you a different image after replacing each pixel value with the maximum value inside the kernel.

  • Step 2: check if the cornerness value of each pixel of the original response image corresponds to the maximum value specified in the dilatation step. If not, then obviously there is a better angle in the neighborhood.

+3
source

If you are looking for some built-in functions, FilterEngine will help you create your own filter (core).

http://docs.opencv.org/modules/imgproc/doc/filtering.html#filterengine

In addition, I would recommend some kind of noise reduction, usually blurring, before each treatment. That is, if you really do not want the image to be raw.

+2
source

Source: https://habr.com/ru/post/1412806/


All Articles