Mustafa Göl
Mustafa Göl

Reputation: 63

Finding Nearest Pixel Value with OpenCV

I want to find the nearest (R, G, B) values in frame using C++ using OpenCV. (R, G, B) values are given. Is there any function or solution in OpenCV? I searched on Internet but I couldn't find. Ordinary solution causes memory problems and it works slow because I want to find 256 different colors. Any suggestion or code would be very helpful?

Upvotes: 3

Views: 1863

Answers (1)

Andrzej Pronobis
Andrzej Pronobis

Reputation: 36096

Below, you will find a code snippet that calculates L1 distance between RGB color values of each pixel and the RGB value you look for. Then, it returns the location of the pixel with minimum distance.

This code is just an example, based on L1 distance between RGB values. That distance DOES NOT reflect the human perception of color difference. There is a choice of distances that you should use instead if you would like to find a pixel that will look most similar to a human eye. Check out this Wikipedia page on Color Difference for a list of such distances. Once you decide on one, it will be very easy to modify the code below to use that distance instead of L1. If your application is very simple, you might be able to get away with the code below as is.

  // RGB values of the color you are looking for
  int r = 0;
  int g = 0;
  int b = 255;

  // Load image
  cv::Mat img = cv::imread("image.png");

  // Split image into channels
  cv::Mat channels[3];
  cv::split(img, channels);

  // Find absolute differences for each channel
  cv::Mat diff_r;
  cv::absdiff(channels[2], r, diff_r);
  cv::Mat diff_g;
  cv::absdiff(channels[1], g, diff_g);
  cv::Mat diff_b;
  cv::absdiff(channels[0], b, diff_b);

  // Calculate L1 distance
  cv::Mat dist = diff_r + diff_g + diff_b;

  // Find the location of pixel with minimum color distance
  cv::Point minLoc;
  cv::minMaxLoc(dist, 0, 0, &minLoc);

  // Get the color of a pixel at minLoc
  cout << img.at<cv::Vec3b>(minLoc) << endl;

Upvotes: 3

Related Questions