2012-06-19 35 views
8

Estoy desarrollando un proyecto usando java para identificar componentes usando el paquete opencv pero soy nuevo en javacv y solo quiero saber cómo identificar rectángulos en una imagen fuente particular, por favor puede alguna persona de experiencia dar alguna línea de guía básica para archivar este tarea. Intento usar la coincidencia de plantilla aquí pero puede identificar el tamaño exacto del rectángulo solamente. Pero en mi caso, ¿necesito identificar el rectángulo de longitud variable?Cómo identificar cuadrado o un rectángulo con longitudes y ancho variable mediante el uso de javacv?

import java.util.Arrays; 
import static com.googlecode.javacv.cpp.opencv_core.*; 
import static com.googlecode.javacv.cpp.opencv_imgproc.*; 
import static com.googlecode.javacv.cpp.opencv_highgui.*; 
public class TestingTemplate { 
public static void main(String[] args) { 
//Original Image 
IplImage src = cvLoadImage("src\\lena.jpg",0); 
//Template Image 
IplImage tmp = cvLoadImage("src\\those_eyes.jpg",0); 
//The Correlation Image Result 
IplImage result = cvCreateImage(cvSize(src.width()-tmp.width()+1, src.height()-tmp.height()+1), IPL_DEPTH_32F, 1); 
//Init our new Image 
cvZero(result); 
cvMatchTemplate(src, tmp, result, CV_TM_CCORR_NORMED); 

double[] min_val = new double[2]; 
double[] max_val = new double[2]; 

//Where are located our max and min correlation points 
CvPoint minLoc = new CvPoint(); 
CvPoint maxLoc = new CvPoint(); 
cvMinMaxLoc(result, min_val, max_val, minLoc, maxLoc, null); //the las null it's for 
optional mask mat() 

System.out.println(Arrays.toString(min_val)); //Min Score 
System.out.println(Arrays.toString(max_val)); //Max Score 

CvPoint point = new CvPoint(); 
point.x(maxLoc.x()+tmp.width()); 
point.y(maxLoc.y()+tmp.height()); 
cvRectangle(src, maxLoc, point, CvScalar.WHITE, 2, 8, 0); //Draw the rectangule result in original img. 
cvShowImage("Lena Image", src); 
cvWaitKey(0); 
//Release 
cvReleaseImage(src); 
cvReleaseImage(tmp); 
cvReleaseImage(result); 
} 
} 

Por favor alguien puede ayudar a lograr esto

+2

cuadrados? Los escuderos son más duros. –

+0

Dave: ¿Podrías proporcionar alguna línea del gremio para archivar esto> –

+2

¿Es squire o SQUARE? si no, ¿qué es escudero? google dice que es una armadura de soldados. ¿Es eso lo que quieres? Mejor agregar una imagen. –

Respuesta

9

(Por lo tanto, se fija como cuadrado.)

Para la detección cuadrada, OpenCV viene con algunas muestras de este. Los códigos están en C++, C, Python. Espero que puedas llevar esto a JavaCV.

C++ code, Python Code.

sólo voy a ilustrar cómo funciona:

1 - En primer lugar, dividir la imagen a aviones R, G, B.

2 - A continuación, para cada plano realizar detección de bordes, y además de que, umbral para diferentes valores como 50, 100, .... etc.

3 - y en todos estos binario imágenes, encuentran contornos (recuerde que está procesando una gran cantidad de imágenes, por lo que puede ser un poco lento, si usted no quiere, puede eliminar algunos valores de umbral).

4 - Después de encontrar los contornos, elimine algunos pequeños ruidos no deseados por filtrando según el área.

5 - Luego, se aproxima al contorno. (More about contour approximation).

6 - Para un rectángulo, le dará las cuatro esquinas. Para otros, se darán las esquinas correspondientes.

Filtre estos contornos con respecto al número de elementos en el contorno aproximado que debe ser cuatro, que es igual que el número de esquinas. En primer lugar propiedad del rectángulo.

7 - A continuación, puede haber algunas formas con cuatro esquinas pero no con rectángulos. Así que tomamos segunda propiedad de rectángulos, es decir, todos los ángulos interiores son 90. Así nos encontramos con el ángulo en todas las esquinas utilizando el siguiente relación:

enter image description here

Y si cos (theta) < 0,1, es decir theta> 84 grados, que es un rectángulo.

8 - Entonces ¿qué pasa con la plaza? utilizar su propiedad, que todos los lados son iguales.

Puede encontrar la distancia entre dos puntos por la relación como se muestra arriba. Compruebe si todos son iguales, entonces ese rectángulo es un cuadrado.

Así es como funciona el código.

A continuación se muestra la salida Me aplicar por encima de código que se cita en una imagen:

enter image description here

EDIT:

Se ha preguntado cómo quitar el rectángulo detectado en la frontera. Es porque, opencv encuentra objetos blancos en fondo negro, también lo es el borde. Invertir la imagen usando la función cv2.bitwise_not() resolverá el problema. obtenemos el resultado de la siguiente manera:

enter image description here

usted puede encontrar más información sobre el contorno aquí: Contours - 1 : Getting Started

+0

¿Puede explicar cómo puedo obtener rectángulos con un ancho inferior al específico? De hecho, necesito quitar esos grandes rectángulos que se muestran en la imagen (bordes). –

+0

Ese borde rectángulo grande se detecta porque, los contornos de OpenCV encuentran objetos blancos en fondo negro. Así que haz cuadrados blancos, es decir, simplemente invierte la imagen. He actualizado la respuesta. –

+0

Entonces, ¿no puedo obtener todos y cada uno de los rectángulos por separado? Si es capaz de hacerlo, puede proporcionar algún ejemplo de código para ello. –

Cuestiones relacionadas