Ho la seguente immagine rilevare rettangoli sfocate su grayscaleimage multimodale
Sto cercando di trovare le coordinate dei pixel di rettangoli principali (quelle tra le linee bianche). Ho provato poche cose ma non riesco a ottenere una soluzione sufficientemente buona. La soluzione non deve essere perfetta ed è ok se non vengono rilevati tutti i rettangoli (specialmente quelli veramente piccoli). Anche se la posizione degli angoli dovrà essere il più precisa possibile, specialmente con quelle più grandi sfocate (sto provando a scrivere un semplice motore AR).
posso chiarire ci sono solo 4 livelli di scala di grigi: 0, 110, 180 e 255 (in caso di stampa, nessuno schermo varierà a causa di un fulmine e ombre)
Finora ho provato alcune cose:
- manuale sogliatura multilivello (a causa delle ombre e diversi fulmini non funzionava)
- adaptive thresholding: 2 problemi:
- unisce 180 e 255 colori al bianco, e 0, 110 in nero
- bordo/posizione d'angolo del sfocate rettangoli (più grandi) non è esatto (si aggiunge sfocatura al rettangolo dell'area)
- rilevamento dei bordi Sobel (angoli di rettangoli sfocate sono più taglienti , ma rileva anche bordi interni in rettangoli, anche tali contorni di bordo non sono sempre chiusi
Sembra combinando quei due pensa qualche modo produrrebbe risultati migliori. O forse qualcuno ha un'idea diversa?
Stavo pensando anche a fare inondazioni, ma era difficile trovare automaticamente un buon punto di semina e una soglia (potrebbero esserci altri oggetti bianchi in background). Inoltre, voglio ottimizzare in seguito questo per l'algoritmo GPU e la piena non è una buona idea per questo.
Di seguito è riportato un codice di esempio ho provato finora:
image = cv2.imread('data/image.jpg');
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow('image', gray)
adaptive = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 601, 0)
cv2.imshow('adaptive', adaptive)
gradx = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=3)
grady = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=3)
abs_gradx = cv2.convertScaleAbs(grady)
abs_grady = cv2.convertScaleAbs(grady)
grad = cv2.addWeighted(abs_gradx, 0.5, abs_grady, 0.5, 0)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
grad = cv2.morphologyEx(grad, cv2.MORPH_OPEN, kernel)
grad = cv2.morphologyEx(grad, cv2.MORPH_CLOSE, kernel)
cv2.imshow('sobel',grad)
#kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7))
#grad = cv2.morphologyEx(grad, cv2.MORPH_OPEN, kernel)
retval, grad = cv2.threshold(grad, 10, 255, cv2.THRESH_BINARY)
cv2.imshow('sobel+morph+thrs',grad)
cv2.waitKey()
Hai considerato il rilevamento degli angoli? – Junuxx
sì, ho provato beneFeaturesToTrack e lì dove molti falsi-possessi – pzo
Giusto per chiarire l'obiettivo. Hai grandi strisce bianche che delineano quadrati, che sono pieni di rettangoli (alcuni dei quali sono anche quadrati). Vuoi gli angoli dei grandi quadrati, gli angoli dei piccoli rettangoli che riempiono i quadrati o entrambi? – Hammer