2012-05-16 1 views
4

Quelques détails sur mon problème:OpenCV image filtre - remplacer le noyau avec maximum local

Je suis en train de réaliser le détecteur d'angle dans OpenCV (un autre algorithme, qui sont intégrés: Canny, Harris, etc.) .

J'ai une matrice remplie avec les valeurs de réponse. La plus grande valeur de réponse est la plus grande probabilité de coin détecté.

J'ai un problème, au voisinage d'un point il y a peu de coins détectés (mais il n'y en a qu'un). Je dois réduire le nombre de faux coins détectés.

problème exact:

je dois marcher à travers la matrice avec un noyau, calculer la valeur maximale de chaque noyau, laisser des valeurs valeur maximale, mais d'autres dans le noyau faire est égal à zéro.

Existe-t-il des fonctions OpenCV intégrées pour cela?

+0

Vous n'êtes pas seulement à la recherche des maxima locaux? Comme ici: http://stackoverflow.com/questions/5550290/find-local-maxima-in-grayscale-image-using-opencv –

+1

Je n'ai pas besoin de maximums locaux dans chaque noyau, mais j'ai besoin d'un tel filtre, –

+0

Je ne suis pas certain de comprendre ce que vous voulez dire, mais dans tous les cas, je le restreindrai à un noyau (ou à un retour sur investissement, et je déplacerai ce ROI dans l'image) en utilisant MinMaxLoc devrait fonctionner non? Comme dans leur commentaire. –

Répondre

14

Voilà comment je le ferais:

  1. Créer un noyau, il définit un quartier de pixels.
  2. Créez une nouvelle image en dilatant votre image en utilisant ce noyau. Cette image dilatée contient la valeur de voisinage maximale pour chaque point.
  3. Effectue une comparaison d'égalité entre ces deux tableaux. Chaque fois qu'ils sont égaux, il s'agit d'un maximum de voisinage valide et il est défini sur 255 dans le tableau de comparaison.
  4. Multipliez le tableau de comparaison et le tableau d'origine ensemble (mise à l'échelle appropriée).
  5. Ceci est votre dernier tableau, contenant uniquement les maxima de voisinage.

Ceci est illustré par ces zoomé images:

9 pixel par 9 image originale pixel:

enter image description here

Après traitement avec 5 par 5 noyau de pixels, seul le voisinage local maxima restent (ie.maxima séparés par plus de 2 pixels à partir d'un pixel d'une valeur plus élevée):

enter image description here

Il y a une mise en garde. Si deux maxima voisins ont la même valeur, ils seront tous deux présents dans l'image finale.

Voici un code Python qui le fait, il devrait être très facile à convertir en 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) 

Je ne savais pas jusqu'à présent, mais est ce que @sansuiso a suggéré dans son/sa réponse .

C'est peut-être mieux illustré avec cette image, avant:

enter image description here

après le traitement avec un 5 par 5 noyau:

enter image description here

régions solides sont dues à la commune locale valeurs maximales.

+0

Merci. Oui, je vois, c'est la réalisation de l'idée étendue de @ sansuiso. –

+0

@Innuendo - oui, c'est drôle, je n'ai pas lu leur réponse jusqu'à ce que je poste, il m'a fait sourire;) – fraxel

+0

@fraxel, j'ai remarqué votre réponse seulement après avoir répondu à une question connexe :) Dans ma réponse, je suggère comment faire face avec des pixels avec des valeurs égales (plateaux). http://stackoverflow.com/a/21023493 – killogre

3

Je suggère une procédure en 2 étapes d'origine (il peut exister des approches plus efficaces), qui utilise OpenCV fonctions intégrées:

  1. Etape 1: dilatation morphologique avec un noyau carré (correspondant à votre quartier). Cette étape vous donne une autre image, après avoir remplacé chaque valeur de pixel par la valeur maximale à l'intérieur du noyau. Étape 2: Tester si la valeur de la corné de chaque pixel de l'image de réponse originale est égale à la valeur maximale donnée par l'étape de dilatation. Si non, alors il existe évidemment un meilleur coin dans le quartier.