在opencv中读取像素的HSV值

发布于 2024-12-11 11:23:57 字数 2159 浏览 0 评论 0原文

你会如何读取 HSV 格式而不是 RGB 格式的像素值?下面的代码以 RGB 格式读取圆心的像素值。 HSV 的读数值有很大差异吗?

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

how would you go about reading the pixel value in HSV format rather than RGB? The code below reads the pixel value of the circles' centers in RGB format. Is there much difference when it comes to reading value in HSV?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

戒ㄋ 2024-12-18 11:23:57

如果您使用 C++ 接口,则可以使用

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

cvtColor 的文档了解更多信息。

更新:

以缓慢的方式读取和写入像素(假设 HSV 值存储为 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)

使用 image.at<...>(x, y) (doc,向下滚动很多)如果你想操作每个像素,符号是相当慢的。 文档中有一篇文章介绍如何更快地访问像素。您也可以像这样应用迭代器方法:

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
}

If you use the C++ interface, you can use

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

See the documentation for cvtColor for more information.

Update:

Reading and writing pixels the slow way (assuming that the HSV values are stored as a 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)

Using the image.at<...>(x, y) (doc, scroll down a lot) notation is quite slow, if you want to manipulate every pixel. There is an article in the documentation on how to access the pixels faster. You can apply the iterator method also like this:

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文