reconocimiento procesamiento introduccion imagenes imagen curso con binarizar artificial java opencv face-detection image-recognition vision

java - procesamiento - Detecta retratos rectangulares de personas en imágenes con OpenCV.



reconocimiento de imagenes python (1)

Tengo muchas imágenes de anuarios con retratos de personas y estoy tratando de construir un algoritmo que detecte esos retratos. Al menos, para detectar retratos rectangulares correctos. Ejemplo 1 Ejemplo 2

Estoy tratando de investigar tres direcciones:

  1. Detección de rostro
  2. Detección de rectángulos oscuros (ya que los retratos suelen ser formas más oscuras sobre un fondo más brillante)
  3. Nombres de personas extraídos de textos de OCR

Al combinar los resultados de los tres algoritmos anteriores, espero obtener alguna metodología, que será aplicable a muchas páginas de anuarios diferentes.

Agradecería cualquier ayuda para la detección de rectángulos. Comencé con Java y OpenCV 3.

Aquí está mi código aplicado para una imagen :

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);

En este punto, tengo tal resultado:

Tratando de encontrar contornos desde los bordes de arriba:

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);

Obteniendo este resultado:

Pero no estoy seguro de cómo extraer rectángulos de esos contornos ya que muchas de las líneas están incompletas.

Volviendo a los bordes y tratando de encontrar líneas verticales y horizontales usando 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); } } }

Resultado:

Al igual que con los contornos, todavía no veo rectángulos correctos que pueda detectar. ¿Podrías ayudarme con una dirección correcta? Tal vez hay una forma más fácil de realizar esta tarea?


No es una respuesta completa pero puede ser útil.

Obtengo la imagen de abajo con el siguiente código.

para entender el código, puede consultar mi respuesta anterior en http://answers.opencv.org/question/85884

Si parece prometedor intentaremos mejorarlo juntos.

#include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> using namespace cv; int main(int argc, char** argv) { Mat img = imread("e:/test/twHVm.jpg"); if (img.empty()) return -1; Mat resized, gray, reduced_h, reduced_w; resize(img, resized, Size(), 1, 1); cvtColor(resized, gray, CV_BGR2GRAY); reduce(gray, reduced_h, 0, REDUCE_AVG); reduce(gray, reduced_w, 1, REDUCE_AVG); for (int i = 0; i < img.cols; i++) { if (reduced_h.at<uchar>(0, i) > 200) // this is experimental value line(resized, Point(i, 0), Point(i, img.rows), Scalar(0, 255, 0), 1); } for (int i = 0; i < img.rows; i++) { if (reduced_w.at<uchar>(i, 0) > 225) // this is experimental value line(resized, Point(0, i), Point(img.cols, i), Scalar(0, 255, 0), 1); } imshow("result", resized); waitKey(0); return 0; }