2012-10-30 10 views
5

Mam następujący obraz rectangle pattern boardwykrywania nieostrym prostokątów na multimodalnego grayscaleimage

próbuję znaleźć współrzędne pikselowe głównych prostokąty (te między białymi liniami). Próbowałem kilku rzeczy, ale nie mogę uzyskać wystarczająco dobrego rozwiązania. Rozwiązanie nie musi być idealne i jest w porządku, jeśli nie wszystkie prostokąty zostaną wykryte (szczególnie te naprawdę małe). Chociaż lokalizacja narożników będzie musiała być tak dokładna, jak to tylko możliwe, szczególnie w przypadku większych rozmytych (próbuję napisać prosty silnik AR).

mogę wyjaśnić, istnieją tylko 4 poziomy szarości: 0, 110, 180 i 255 (przy drukowaniu, nie ekran będzie się zmieniać z powodu wyładowań atmosferycznych i cienie)

Do tej pory próbowałem kilka rzeczy:

  1. instrukcja wielopoziomowe obcinanie (z powodu cieni i inny piorun to nie działa)
  2. adaptacyjne obcinanie: 2 problemy:
    • łączy 180 i 255 kolorów do białego, i 0, 110 do czarnej
    • krawędzi/lokalizacji narożnej rozmytych (większych) prostokątów nie jest dokładna (nie dodaje rozmycia prostokąt Powierzchnia)
  3. wykrywania Sobel krawędź (narożniki niewyraźne prostokątów są bardziej ostry , ale wykrywa również wewnętrzne krawędzie w prostokątach, a także kontury krawędzi nie zawsze są zamknięte

Wygląda na to, że połączenie tych dwóch myśli w jakiś sposób przyniesie lepsze wyniki. A może ktoś ma inny pomysł?

Zastanawiałem się również nad robieniem zapasu, ale trudno było znaleźć na pewno dobry punkt wysiewu i próg automatycznie (w tle mogą być jakieś inne białe obiekty). Poza tym będę chciał zoptymalizować to później w przypadku GPU, a algorytm wypełniania nie jest do tego odpowiedni.

Poniżej przykładowy kod próbowałem dotąd:

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() 
+1

Czy zastanawiałeś się nad wykrywaniem narożników? – Junuxx

+0

Tak, próbowałem goodFeaturesToTrack i tam, gdzie wielu fałszywych-possitives – pzo

+1

Wystarczy, aby wyjaśnić cel. Masz duże białe paski wyznaczające kwadraty, które są pełne prostokątów (niektóre z nich również są kwadratami). Czy chcesz narożników dużych kwadratów, narożników małych prostokątów wypełniających kwadraty lub jedno i drugie? – Hammer

Odpowiedz

3

Wierzę, że twoja odpowiedź polega na użyciu transformacji Hough, aby wykryć linie, rozszerzając te linie, aby rozciągnąć przerwy pomiędzy ciemniejszymi kwadratami, a następnie szukając przecięć wyznaczających rogi. Miałem krótki luz w Matlab i mają pochodzić z następujących, to nie jest idealne, ale powinny pokazać potencjał:

% Open image 
i = imread('http://i.stack.imgur.com/kwcXm.jpg'); 

% Use a sharpening filter to enhance some of the edges 
H = fspecial('unsharp'); 
i = imfilter(i, H, 'replicate'); 
% Detect edge segments using canny 
BW = edge(i, 'canny'); 

% Apply hough transform to edges 
[H, T, R] = hough(BW, 'RhoResolution', 0.5, 'Theta', -90:0.5:89.5); 
% Find peaks in hough transform 
P = houghpeaks(H, 5, 'threshold', ceil(0.1*max(H(:)))); 
% Extract lines from peaks, extending partial lines 
lines = houghlines(BW, T, R, P, 'FillGap', 100, 'MinLength', 5); 

% Plot detected lines on image 
imshow(i); hold on; 
for k = 1:length(lines) 
    xy = [lines(k).point1; lines(k).point2]; 
    plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green'); 
end 

z efektu końcowego:

Final Result

Oczywiście tam pokój do ulepszenia, z kilkoma liniami, które wciąż są do wykrycia, ale jeśli poprawianie różnych parametrów nie działa, możesz wziąć początkowy wynik i wyszukać więcej linii o podobnych kątach, aby uzyskać bardziej kompletny zestaw. Narożniki można następnie znaleźć z przecięć, które powinny być wystarczająco proste, aby wyodrębnić.

0

chciałbym spróbować wykonać następujące czynności:

  • Hough transform wykryć wszystkie linie proste
  • Poszukaj zestawów linii równoległych, które są :
    • Wystarczająca odległość od siebie
    • S eparated przez jaśniejszym kolorem

Istnieje kilka rzeczy, które sprawiają, że problem trudniejsze niż musi być:

  • zniekształcenia perspektywy
  • Zmiany w oświetlenie, drobne cienie

Jeśli możesz zminimalizować powyższe, może to pomóc w rozwiązaniu problemu.

Powiązane problemy