2011-12-21 21 views
12

Como una especie de "proyecto de vacaciones" estoy jugando con OpenCV y quiero detectar y medir cosas.OpenCV C++/Obj-C: Detección adecuada de objetos

flujo de trabajo actual (etapa temprana - detección):

  1. Convertir a escala de grises (cv :: cvtColor)
  2. Aplicar umbral adaptativo (cv :: adaptiveThreshold)
  3. Aplicar detección de bordes de Canny (cv: : Canny)
  4. contornos Encontrar (cv :: findContours)

Mi resultado es un poco cutre y no estoy seguro de cuál es el Rig t dirección para ir. Ya tengo cvBlob trabajando en mi configuración actual (OSX 10.7.2, Xcode 4.2.1) ¿es una mejor manera de hacerlo? Si es así, ¿cómo puedo implementarlo de la manera correcta?

¿O necesito primero la resta de fondo? He intentado eso, pero no era capaz de encontrar contornos después

Aquí está mi imagen: image to measure

Y ese es mi salida, cuando dibujo mis contornos de nuevo en la primera imagen: output

ACTUALIZACIÓN

lo tengo trabajo en mi programm y mi salida se ve un poco diferente ...

- (IBAction)processImage:(id)sender 
{ 
    cv::Mat forground = [[_inputView image] CVMat]; 
    cv::Mat result = [self isolateBackground:forground]; 
    [_outputView setImage:[NSImage imageWithCVMat:result]]; 
} 

- (cv::Mat)isolateBackground:(cv::Mat &)_image 
{ 
    int rh = 255, rl = 100, gh = 255, gl = 0, bh = 70, bl = 0; 
    cv::cvtColor(_image, _image, CV_RGB2HSV_FULL); 
    cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5)); 
    cv::Mat bgIsolation; 
    cv::inRange(_image, cv::Scalar(bl, gl, rl), cv::Scalar(bh, gh, rh), bgIsolation); 
    bitwise_not(bgIsolation, bgIsolation); 
    erode(bgIsolation, bgIsolation, cv::Mat()); 
    dilate(bgIsolation, bgIsolation, element); 
    return bgIsolation; 
} 

Respuesta

10

Esta podría ser una especie de truco, pero ya que es un "proyecto de vacaciones", voy a publicar de todos modos :)

¿Ha intentado aislar el fondo y luego invertir la máscara (esto no suponga nada el fondo es un objeto, pero podría funcionar para lo que quieras).

a continuación es el resultado que obtuve mediante la función de OpenCV inRange: enter image description here

Es posible que desee para suavizar la imagen (pre-proceso) con GuassianBlur para deshacerse de algunos de los jagginess. Usé un kernel de dilatación mayor que kernel de erosión (5x5 vs. 3x3) para eliminar algunos píxeles ruidosos. El alisamiento puede ayudar a que también ajustar los umbrales pueda hacer que la erosión sea innecesaria. Pero, eso debería hacerte comenzar.

Por último, aquí está mi rápida pequeño fragmento de código que utiliza para encontrar esta gama:

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <vector> 

using namespace cv; 
using namespace std; 

int main(int argc, char** argv) 
{ 
    Mat src = imread("test.jpg"); 


    int rh = 255, rl = 100, gh = 255, gl = 0, bh = 70, bl = 0; 

    string windowName = "background"; 
    namedWindow(windowName); 

    createTrackbar("rh", windowName, &rh, 255); 
    createTrackbar("rl", windowName, &rl, 255); 
    createTrackbar("gh", windowName, &gh, 255); 
    createTrackbar("gl", windowName, &gl, 255); 
    createTrackbar("bh", windowName, &bh, 255); 
    createTrackbar("bl", windowName, &bl, 255); 

    // for dilation 
    Mat element = getStructuringElement(MORPH_RECT, Size(5, 5)); 

    Mat bgIsolation; 
    int key = 0; 
    do 
    { 
     inRange(src, Scalar(bl, gl, rl), Scalar(bh, gh, rh), bgIsolation); 

     bitwise_not(bgIsolation, bgIsolation); 

     erode(bgIsolation, bgIsolation, Mat()); 
     dilate(bgIsolation, bgIsolation, element); 

     imshow(windowName, bgIsolation); 
     key = waitKey(33); 
    } while((char)key != 27); 

    waitKey(); 

    return 0; 
} 

Disfrute del proyecto de vacaciones! Parece divertido :)

+0

¡Muchas gracias! ¿Puedes echar un vistazo a mi código? – dom

+0

@moosgummi La razón por la que obtiene un resultado diferente es porque se está transformando en el espacio de color HSV. Mis umbrales eran para el espacio RGB. Puede usar HSV, pero necesitará encontrar los rangos apropiados para ese espacio. Puede agregar esa conversión de color a mi aplicación de muestra y probarla. Imagino que solo tendrá que preocuparse por los canales de Hue y Saturación ya que el canal de Valor no contiene ninguna información de color (es decir, el rango de Valor no se tocará [0, 255]). ¡Espero que ayude! – mevatron

+0

Ah ok, ¿entonces debería funcionar mejor en RGB?bl, gl y rl son valores azules, verdes y rojos. ¿Estoy en lo cierto? – dom

Cuestiones relacionadas