Ask Your Question
0

detect all range colors on image

asked 2016-10-02 07:32:08 -0500

Tombery gravatar image

I need to parse the image on all available colors. I want to use function - " inRange " to get the coordinates arrays each of the colors. And then by the length of the array to determine which color ranges are present or not. The main point that I do not know how to do - is to define a range of colors. that is, the maximum and minimum color values. The greater the range the more accurate the result. But anycase, there should be no more than 20.

edit retag flag offensive close merge delete

Comments

have a look also in this thread, it might be useful. The use of a lookup table as @pklab proposed might be useful as well.

theodore gravatar imagetheodore ( 2016-10-03 12:31:10 -0500 )edit

2 answers

Sort by ยป oldest newest most voted
1

answered 2016-10-03 03:29:02 -0500

pklab gravatar image

I would use CV_BGR2HSV_FULL color conversion to get all colors within the range of 0..255 included . (For your info, the conversionCV_BGR2HSV returns Hue the range of 0..180 included)

// a sample image
cv::Mat src = (cv::Mat_<Vec3b>(3, 3) <<
    Vec3b(0, 0, 0), Vec3b(128, 128, 128), Vec3b(255, 255, 255),
    Vec3b(255, 0, 0),Vec3b(0, 255, 0), Vec3b(0, 0, 255), 
    Vec3b(255, 255, 0), Vec3b(255, 0, 255), Vec3b(0, 255, 255));
CV_Assert(src.type() == CV_8UC3);

cv::Mat hsvFull;
// this returns hue within the range 0..255
cv::cvtColor(src, hsvFull, CV_BGR2HSV_FULL);
vector<uchar> colorsCount(256,0);
Scalar pixel;
uchar color;
int maxColor=0, minColor=INT16_MAX;
// Scan image to count colors
// see http://docs.opencv.org/3.1.0/db/da5/tutorial_how_to_scan_images.html
// for alternative/efficient way to scan images
for (int r = 0; r < hsvFull.rows; r++)
{
    for (int c = 0; c < hsvFull.cols; c++)
    {
        pixel = hsvFull.at<Vec3b>(Point(c, r));
        color = pixel(0);
        colorsCount[color] +=1;
        if (color < minColor) minColor = color;
        if (color > maxColor) maxColor = color;
    }
}
int colorRange = maxColor - minColor;
int minCount, maxCount;
minCount = colorsCount[minColor];
maxCount = colorsCount[maxColor];

If you like you can apply a lookup table to reduce colors to %20

Mat lookUpTable(1, 256, CV_8U);
Mat hsvDiscrete;
uchar* p = lookUpTable.ptr();
for (int i = 0; i < 256; ++i)
    p[i] = i - i % 20;
LUT(hsvFull, lookUpTable, hsvDiscrete);
// get back an BGR image ready to show
Mat dst;
cvtColor(hsvDiscrete, dst, CV_HSV2BGR_FULL);
imshow("Src", src);
imshow("Discrete", dst);
waitKey(0);
edit flag offensive delete link more
0

answered 2016-10-04 10:42:07 -0500

Guyygarty gravatar image

Hi,

Do you need the actual pixel coordinates or just the number of pixels?

If the latter you would probably be better off using calcHist to generate a histogram of the hue value. See example here:

http://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html

guy

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2016-10-02 07:32:08 -0500

Seen: 1,495 times

Last updated: Oct 04 '16