Mam wiele zdjęć roczników z portretami ludzi i staram się zbudować algorytm, który wykryje te portrety. Przynajmniej, aby wykryć prawidłowe prostokątne portrety. Example 1Example 2Wykryj prostokątne portrety ludzi na obrazach z OpenCV
staram się badać trzech kierunkach:
- wykrywania twarzy
- Ciemne prostokąty wykrywanie (Od portrety są zwykle ciemniejsze kształty na jaśniejszym tle)
- Ludzie ekstrakcji nazwa od OCR'ed teksty
Łącząc wyniki trzech powyższych algorytmów, mam nadzieję uzyskać pewną metodologię, która będzie miała zastosowanie dla wielu różnych stron roczników.
Byłbym bardzo wdzięczny za każdą pomoc w wykryciu prostokątów. Zacząłem Java i OpenCV 3.
Tu jest mój kod stosowany dla an image:
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat source = Imgcodecs.imread("Path/to/image", Imgcodecs.CV_LOAD_IMAGE_ANYCOLOR);
Mat destination = new Mat(source.rows(), source.cols(), source.type());
Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2GRAY);
Imgproc.GaussianBlur(destination, destination, new Size(5, 5), 0, 0, Core.BORDER_DEFAULT);
int threshold = 100;
Imgproc.Canny(destination, destination, 50, 100);
Imgproc.Canny(destination, destination, threshold, threshold*3);
W tym momencie mam taki wynik:
próbując znaleźć kontury od krawędzi powyżej:
List<MatOfPoint> contourDetections = new ArrayList<>();
Mat hierarchy = new Mat();
// Find contours
Imgproc.findContours(destination, contourDetections, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// Draw contours
Imgproc.drawContours(source, contours, -1, new Scalar(255,0,0), 2);
Nie wiem jednak, jak wyodrębnić prostokąty z tych konturów, ponieważ wiele linii jest niekompletnych.
Wracając do krawędzi i próbuje znaleźć pionowe i poziome linie korzystające HoughLinesP:
Mat lines = new Mat();
int thre = 50;
int minLineSize = 250;
int lineGap = 80;
int ignoreLinesShorter = 300;
Imgproc.HoughLinesP(destination, lines, 1, Math.PI/180, thre, minLineSize, lineGap);
for(int c = 0; c < lines.rows(); c++) {
double[] vec = lines.get(c, 0);
double x1 = vec[0],
y1 = vec[1],
x2 = vec[2],
y2 = vec[3];
// Filtering only verticat and horizontal lines
if(x1 == x2 || y1 == y2) {
// Filtering out short lines
if(Math.abs(x1 - x2) > ignoreLinesShorter || Math.abs(y1 - y2) > ignoreLinesShorter) {
Point start = new Point(x1, y1);
Point end = new Point(x2, y2);
// Draw line
Imgproc.line(source, start, end, new Scalar(0,0,255), 2);
}
}
}
Wynik:
jak z konturami nie, ja wciąż widząc, że odpowiednie prostokąty Mogłem wykryć. Czy możesz mi pomóc we właściwym kierunku? Być może istnieje łatwiejszy sposób wykonania tego zadania?
kontury są niepełne ponieważ krawędzie są niekompletne. Czy próbowałeś niższych wartości progowych w Canny? Możesz także filtrować mniejsze kontury według rozmiaru za pomocą opcji 'contourArea'. –
Co powiecie na: * zwiększenie * progu konturu, a następnie rozciągnięcie wszystkich linii pionowych i poziomych? –