Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++, OpenCV] Detekcja okręgu na zdjęciu jpg

Ostatnio zmodyfikowano 2012-10-07 19:15
Autor Wiadomość
kasztanowy_jim
Temat założony przez niniejszego użytkownika
[C++, OpenCV] Detekcja okręgu na zdjęciu jpg
» 2012-10-07 14:05:19
Mam gorącą prośbę o pomoc do kogoś, kto ogrania trochę przetwarzanie obrazów albo/i Open CV. Chcę wykryć za pomocą funkcji HoughCircles (chyba że istnieje jakaś inna, o której nie wiem) białą kulkę zarejestrowaną na zdjęciu jpg dodanym w załączniku. Używam OpenCV 2.1 i Visuala 2010 Express, pod Win7 x64. Niestety, mimo sporego kombinowania nie umiem ustawić parametrów tej funkcji tak, żeby wykryć tą białą kuleczkę. Nie wiem, czy podaję nieodpowiednie parametry, czy ta kuleczka jest zbyt mała/zbyt rozmazana.

Niżej umieszczam kod. Zamieniam obraz kolorowy na odcienie szarości. Dalej zastanawiam się nad użyciem funkcji GaussianBlur, żeby rozmyć obrazek i pozbyć się szumów - niestety, nie udało mi się dobrać parametru filtru tak, żeby jakoś zredukować szumy - obraz po filtracji był bez zmian. Tutaj nie wiem - czy przed szukaniem okręgów użyć Blura czy nie, a jeśli tak, na jakich ustawieniach. I dalej najważniejsze - potrzebuję pomocy przy dobraniu argumentów funkcji HoughCircles tak, żeby wykrywała biała kuleczkę.


C/C++
#include <iostream>
#include <math.h>
#include <cv.h>
#include <highgui.h>
using namespace std;
using namespace cv;
int main()
{
    /* wczytanie zdjecia */
    Mat image;
    image = imread( "mala_kulka.jpg", 1 );
    /* wyswietlenia liczby kolumn i wierszy */
    cout << "Liczba kolumn (szerokosc) : ";
    cout << image.cols << endl;
    cout << "Liczba wierszy (wysokosc) : ";
    cout << image.rows << endl << endl;
   
    /* odczytanie i wyswietlenie kolorow danego pixela (niewazne) */
    /*    cv::Vec3b pixelColor = image.at<cv::Vec3b>(20, 600);
        int p1 = pixelColor[0];
        int p2 = pixelColor[1];
        int p3 = pixelColor[2];
        cout<<p1<<" ; "<<p2<<" ; "<<p3<<endl; */
    /* zmiana rozmiary zdjecia */ /*
    /*   Mat resized(100,100, image.type());
        resize(image, resized, resized.size()); */
   
   
    /* PRZEJSCIE NA SKALE SZAROSCI */
    Mat grayImage;
    cvtColor( image, grayImage, CV_RGB2GRAY );
    /* DETEKCJA KULECZKI */
    vector < Vec3f > circles;
    HoughCircles( grayImage, circles, CV_HOUGH_GRADIENT,
    2, 50, 500, 300, 5, 100 );
   
    cout << "znalezionych okregow: " << circles.size() << endl;
    for( size_t i = 0; i < circles.size(); i++ )
    {
        Point center( cvRound( circles[ i ][ 0 ] ), cvRound( circles[ i ][ 1 ] ) );
        int radius = cvRound( circles[ i ][ 2 ] );
        // draw the circle center
        circle( image, center, 3, Scalar( 252, 3, 0 ), - 1, 8, 0 );
        // draw the circle outline
        circle( image, center, radius, Scalar( 252, 3, 0 ), 3, 8, 0 );
    }
    Mat resized( 800, 800, image.type() );
    resize( image, resized, resized.size() );
    imshow( "Nazwa okna", resized );
   
    waitKey();
    return 0;
}

A oto zdjęcie, na którym pracuję:
link:   http://photoupload.pl/images/2012/10/07/yFs9Y.jpg

Ponownie będę cholernie zobowiązany za pomoc z tematem.
P-66277
DejaVu
» 2012-10-07 15:49:22
P-66309
kasztanowy_jim
Temat założony przez niniejszego użytkownika
» 2012-10-07 18:49:19
Dziękuję bardzo - na razie skupię się na progowaniu, detekcją zajmę się może później.
Niestety, podbijam z kolejnym problemem.

Mam wrzucone wcześniej zdjęcie, przerabiam je na monochromatyczne jak wcześniej, następnie wykonuję progowanie na tym monochromatycznym obrazie. I teraz potrzebuję przeglądać wszystkie piksele tego sprogowanego zdjęcia i odczytywać wartość. Problem polega na tym, że nie wiem, i nie mogę doczytać w dokumentacji, w jaki sposób teraz jest reprezentowany kolor pixela. Myślałem że analogicznie, skoro progowałem aby mieć punkty tylko całkiem jasne albo tylko całkiem ciemne, to pixele będą miały wartość albo 0,0,0 (czarne) albo 255,255,255 (białe).

Pixele obrazu kolorowego dalo sie odczytac tak:
Vec3b pixelColor = image.at<Vec3b>(1999,1999);

Pixele obrazu najpierw zamienionego na monochromatyczny funkcja
cvtColor(image, grayImage, CV_RGB2GRAY)
 ,a potem sprogowanego funkcja
threshold(grayImage, progowane, prog, 255, THRESH_BINARY);
 niby dla malych wspolrzednych pikseli mozna odczytac tak samo, ale potem wyraznie sie cos rozjezdza i pomimo iż np. sprogowany obraz ma wymiar 3000x3500, to nie mozna juz odczytac piksela (2000,2500) - więc jestem przekonany, że taki sposób jest zły. Pewnie w dokumentacji stoi jak byk, w jaki sposób z obiektu cv::Mat monochromatycznego, po progowaniu, odczytać wartość pixela. Pewnie trzeba użyć czegoś innego zamiast Vec3b - niestety ani double, ani float nie działały. Nie mogę sobie z tym poradzić - może ktoś będzie w stanie mi pomóc.
P-66332
DejaVu
» 2012-10-07 19:15:13
Jeden temat = jeden problem. Trzymaj się tej zasady :) Temat dotyczy detekcji okręgu, a nie odczytywania pikseli.
Frazy, które należy wpisać w wyszukiwarkę google:
P-66336
« 1 »
  Strona 1 z 1