在opencv中读取像素的HSV值 [英] Read HSV value of pixel in opencv

查看:1265
本文介绍了在opencv中读取像素的HSV值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您将如何读取HSV格式而不是RGB的像素值?下面的代码以RGB格式读取圆心的像素值.读取HSV中的值是否有很大差异?

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

推荐答案

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

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

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

有关更多信息,请参见 cvtColor文档.

See the documentation for cvtColor for more information.

更新:

以慢速方式读取和写入像素(假设HSV值存储为cv::Vec3b( doc ))

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)

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

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
}

这篇关于在opencv中读取像素的HSV值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆