Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the image pixel at real locations in opencv?

Tags:

I want to retrieve the rgb of a pixel in the image. But the location is not integer location but real values (x,y). I want a bilinear interpolated value. How could I do it opencv?

Thanks a lot

like image 961
Shan Avatar asked Nov 08 '12 23:11

Shan


People also ask

How do I get the pixel value of an image in OpenCV?

Figure 5: In OpenCV, pixels are accessed by their (x, y)-coordinates. The origin, (0, 0), is located at the top-left of the image. OpenCV images are zero-indexed, where the x-values go left-to-right (column number) and y-values go top-to-bottom (row number). Here, we have the letter “I” on a piece of graph paper.


1 Answers

There is no simple function for subpixel access but I can suggest you few options:

  1. Use getRectSubPix and extract 1 pixel region:

    cv::Vec3b getColorSubpix(const cv::Mat& img, cv::Point2f pt) {     cv::Mat patch;     cv::getRectSubPix(img, cv::Size(1,1), pt, patch);     return patch.at<cv::Vec3b>(0,0); } 
  2. Use more flexible but less precise remap with one-pixel map:

    cv::Vec3b getColorSubpix(const cv::Mat& img, cv::Point2f pt) {     cv::Mat patch;     cv::remap(img, patch, cv::Mat(1, 1, CV_32FC2, &pt), cv::noArray(),         cv::INTER_LINEAR, cv::BORDER_REFLECT_101);     return patch.at<cv::Vec3b>(0,0); } 
  3. Implement bilinear interpolation yourself, as it is not a rocket science:

    cv::Vec3b getColorSubpix(const cv::Mat& img, cv::Point2f pt) {     assert(!img.empty());     assert(img.channels() == 3);      int x = (int)pt.x;     int y = (int)pt.y;      int x0 = cv::borderInterpolate(x,   img.cols, cv::BORDER_REFLECT_101);     int x1 = cv::borderInterpolate(x+1, img.cols, cv::BORDER_REFLECT_101);     int y0 = cv::borderInterpolate(y,   img.rows, cv::BORDER_REFLECT_101);     int y1 = cv::borderInterpolate(y+1, img.rows, cv::BORDER_REFLECT_101);      float a = pt.x - (float)x;     float c = pt.y - (float)y;      uchar b = (uchar)cvRound((img.at<cv::Vec3b>(y0, x0)[0] * (1.f - a) + img.at<cv::Vec3b>(y0, x1)[0] * a) * (1.f - c)                            + (img.at<cv::Vec3b>(y1, x0)[0] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[0] * a) * c);     uchar g = (uchar)cvRound((img.at<cv::Vec3b>(y0, x0)[1] * (1.f - a) + img.at<cv::Vec3b>(y0, x1)[1] * a) * (1.f - c)                            + (img.at<cv::Vec3b>(y1, x0)[1] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[1] * a) * c);     uchar r = (uchar)cvRound((img.at<cv::Vec3b>(y0, x0)[2] * (1.f - a) + img.at<cv::Vec3b>(y0, x1)[2] * a) * (1.f - c)                            + (img.at<cv::Vec3b>(y1, x0)[2] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[2] * a) * c);      return cv::Vec3b(b, g, r); } 
like image 181
Andrey Kamaev Avatar answered Sep 29 '22 18:09

Andrey Kamaev