2011-10-22 12 views
1

comment iriez-vous sur la lecture de la valeur de pixel au format HSV plutôt que RVB? Le code ci-dessous lit la valeur de pixel des centres des cercles au format RVB. Y at-il beaucoup de différence quand il s'agit de lire la valeur dans HSV?Lire la valeur HSV du pixel dans opencv

int main(int argc, char** argv) 
{ 
    //load image from directory 
    IplImage* img = cvLoadImage("C:\\Users\\Nathan\\Desktop\\SnookerPic.png"); 


    IplImage* gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1); 
    CvMemStorage* storage = cvCreateMemStorage(0); 

    //covert to grayscale 
    cvCvtColor(img, gray, CV_BGR2GRAY); 

    // This is done so as to prevent a lot of false circles from being detected 
    cvSmooth(gray, gray, CV_GAUSSIAN, 7, 7); 

    IplImage* canny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1); 
    IplImage* rgbcanny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3); 
    cvCanny(gray, canny, 50, 100, 3); 

    //detect circles 
    CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, 35.0, 75, 60,0,0); 
    cvCvtColor(canny, rgbcanny, CV_GRAY2BGR); 

    //draw all detected circles 
    for (int i = 0; i < circles->total; i++) 
    { 
     // round the floats to an int 
     float* p = (float*)cvGetSeqElem(circles, i); 
     cv::Point center(cvRound(p[0]), cvRound(p[1])); 
     int radius = cvRound(p[2]); 
     //uchar* ptr; 
     //ptr = cvPtr2D(img, center.y, center.x, NULL); 
     //printf("B: %d G: %d R: %d\n", ptr[0],ptr[1],ptr[2]); 
     CvScalar s; 

     s = cvGet2D(img,center.y, center.x);//colour of circle 
     printf("B: %f G: %f R: %f\n",s.val[0],s.val[1],s.val[2]); 

     // draw the circle center 
     cvCircle(img, center, 3, CV_RGB(0,255,0), -1, 8, 0); 

     // draw the circle outline 
     cvCircle(img, center, radius+1, CV_RGB(0,0,255), 2, 8, 0); 

     //display coordinates 
     printf("x: %d y: %d r: %d\n",center.x,center.y, radius); 

    } 

    //create window 
    //cvNamedWindow("circles", 1); 
    cvNamedWindow("SnookerImage", 1); 
    //show image in window 
    //cvShowImage("circles", rgbcanny); 
    cvShowImage("SnookerImage", img); 

    cvSaveImage("out.png", img); 
    //cvDestroyWindow("SnookerImage"); 
    //cvDestroyWindow("circles"); 
    //cvReleaseMemStorage("storage"); 
    cvWaitKey(0); 

    return 0; 
} 

Répondre

6

Si vous utilisez l'interface C++, vous pouvez utiliser

cv::cvtColor(img, img, CV_BGR2HSV); 

Voir the documentation for cvtColor pour plus d'informations.

Mise à jour:

lecture et les pixels d'écriture de la manière lente (en supposant que les valeurs HSV sont stockées sous la forme d'un cv::Vec3b (doc))

cv::Vec3b pixel = image.at<cv::Vec3b>(0,0); // read pixel (0,0) (make copy) 
pixel[0] = 0; // H 
pixel[1] = 0; // S 
pixel[2] = 0; // V 
image.at<cv::Vec3b>(0,0) = pixel; // write pixel (0,0) (copy pixel back to image) 

Utilisation du image.at<...>(x, y) (doc, faites défiler vers le bas une beaucoup) la notation est assez lente, si vous voulez manipuler chaque pixel. Il y a un article dans le documentation on how to access the pixels faster. Vous pouvez appliquer la méthode iterator aussi comme ceci:

cv::MatIterator_<cv::Vec3b> it = image.begin<cv::Vec3b>(), 
        it_end = image.end<cv::Vec3b>(); 
for(; it != it_end; ++it) 
{ 
    // work with pixel in here, e.g.: 
    cv::Vec3b& pixel = *it; // reference to pixel in image 
    pixel[0] = 0; // changes pixel in image 
} 
+1

Je comprends que je peux convertir l'image en TSV mais comment puis-je extraire de la valeur de pixel au format VHS –

+0

Vous devriez être plus explicite dans votre question au sujet de votre problème. J'ai supposé que vous saviez comment accéder aux éléments d'un 'cv :: Mat' puisque vous sembliez être capable de lire les pixels au format RVB. – bjoernz

+0

J'ai ajouté le code que j'ai écrit pour lire la valeur de pixel en RVB. ressemble beaucoup à ce que vous avez suggéré. De toute façon, il peut être fait de la même manière que je l'ai écrit pour RGB? merci –

Questions connexes