0

I am now currently storing my RGB values of the image with a vector <cv::Vec3b>.

To avoid confusion, let me try clarify my question more. For instance I have a vector of size 10. And the values stored are as shown:

 Vector address        RGB Values(R,G,B)
    [0][0][0]=         255,255,255
    [1][1][1]=         40,42,40
    [2][2][2]=         40,42,40
    [3][3][3]=         40,42,40
    [4][4][4]=         40,2,60
    [5][5][5]=         9,9,0
    [6][6][6]=         40,2,60
    [7][7][7]=         40,42,40
    [8][8][8]=         255,255,40
    [9][9][9]=         255,255,40

as observed, The most occurring values is (40,42,40). How do I get these values? I wish to find the most occurring RGB values of the vector. Does anybody have any suggestions, code sample on how I can do it? Thanks.

rockinfresh
  • 2,068
  • 4
  • 28
  • 46
  • 1
    Do you know image histograms? –  Feb 11 '14 at 06:36
  • @bibek subedi, yup, but now I am actually targeting a specific row of the image. While I know how to draw an histogram for a small ROI, I never tried for a single row. Even if it works, I only know how to get the most occurring R, most occurring G, most occurring B, and not the most occurring RGB element. Hope you understand what I mean. – rockinfresh Feb 11 '14 at 06:42
  • In addition, I think if I was too use the histogram method for each row, the program will be super slow. hence I am thinking of using vector and sort out the most occurring element. – rockinfresh Feb 11 '14 at 06:44
  • 1
    without building histogram,how do you sort? –  Feb 11 '14 at 06:51
  • I came across this problem last time, for a std::vector, I learnt my sorting method from this post: http://stackoverflow.com/questions/12049352/determining-most-freq-char-element-in-a-vectorchar, the answer by Phillip Ngan. – rockinfresh Feb 11 '14 at 06:56
  • I am thinking of doing something similar, have tried, but failed. – rockinfresh Feb 11 '14 at 06:56

3 Answers3

2

Lets say your 3D array is array[][][] and at some location (x,y) you got R=200, G=100, B=10 then you will increment the value of array[200][100][10] by 1. Lets at some another location also you again get R=200, G=100, B=10 then again you will increment array[200][100][10] by 1 so, now the total value at array[200][100][10] is 2. You will do the same for all pixel location.

Then, at the end you will find the maximum value in your 3D array and lets say that maximum value is 1000 at array[210][15][10]. This represents that the combination of R.G and B which occurs maximum number of times is "R=210, G=15, B=10"

So, in short we can say that value at [ ][ ][ ] tells you , how many times the combination [R][G][B] has occurred.

skm
  • 5,015
  • 8
  • 43
  • 104
  • Thanks for the method, an upvote and accepted answer for u (: – rockinfresh Feb 12 '14 at 02:21
  • Wish to ask another mini question though. I usually do this method through std::sort, however the sort() function is unable to take in vector type, do you have any idea if there is another method available to do something like sort()? – rockinfresh Feb 12 '14 at 02:24
  • sorry but i didn't understand why do you need to sort the histogram? you just need to find the bin with maximum value which can be done easily for loop (3 for loops in your case). – skm Feb 12 '14 at 07:52
1

I am not very much acquainted with IP. If its just a matter of getting most numbers of occurring RGB objects then it can be done using sort() and equal_range() algorithms present in algorithm.h header file. In the below snippet I have taken example of vector instead of RGB type. This code snippet can be used for your purpose with some changes to find the count of highest occurring object:

    void main() 
{
    vector<int> vecInt;
    vecInt.push_back(0);
    vecInt.push_back(1);
    vecInt.push_back(2);
    vecInt.push_back(3);
    vecInt.push_back(1);
    vecInt.push_back(1);
    vecInt.push_back(1);
    vecInt.push_back(9);
    vecInt.push_back(1);
    vecInt.push_back(0);
    vecInt.push_back(0);

    sort(vecInt.begin(), vecInt.end());
    vector<int>::iterator it;
    it = vecInt.begin();    

    pair<vector<int>::iterator, vector<int>::iterator> pairIter;

    int count = 0;
    for(; it != vecInt.end(); ++it)
    {
            if(it != vecInt.end() )
            {
                pairIter = equal_range(it, vecInt.end(), *it);
            }

        while(pairIter.first != pairIter.second)
        {
        ++count;
        ++(pairIter.first);
        }


    }

}

equal_count(), works on sorted containers and returns a pair of iterators (a range in the sorted container), which contains the value being searched.

pairIter = equal_range(it, vecInt.end(), *it);

Now, we can get the number of items within that pair of iterator using a loop like:

            while(pairIter.first != pairIter.second)
        {
        ++count;
        ++(pairIter.first);
        }

With some changes in this code, I think will solve your purpose.

Anitesh
  • 27
  • 6
1

I think that you can define a three dimensional array and you can do it as mentioned here: http://www.cplusplus.com/forum/articles/7459/

then extract the values of pixel ( Veb3b pixelValue; )at each location of your image and then based upon the R,G and B values (rValue = pixelValue[0]; , gValue = pixelValue[1];,bValue = pixelValue[2];) increment the corresponding bin of your 3D array

skm
  • 5,015
  • 8
  • 43
  • 104
  • Thanks. But not really what I looking for. Basically, I already have done all the storing that you have said, I am using a multidimensional array already and have stored all the values in. I am trying to find out the most occurring RGB Values. – rockinfresh Feb 11 '14 at 08:50
  • i am not sure whether i have understood it correctly or not but once you get such an array then you just need to find the location which has maximum value....the indices of that location will be the highly occuring values of R,G& B. – skm Feb 11 '14 at 08:55
  • Let me try see if I got you correctly, so if at [1][1][1], my RGB value is 243,233,233, that will be the highly occurring value of RGB? If that's so, that's not what I am trying to do. I am trying to find for instance is the value of "200,10,10," appears the most times(let's say 6 times) in maybe a vector of size 10, then I want those values. Its value is lower than the [1][1][1] still though. – rockinfresh Feb 11 '14 at 09:10
  • No..its not like that. I have added an another answer to explain it better..have a look on it. – skm Feb 11 '14 at 09:52
  • 1
    @rockinfresh: when you see the value 243,233,233 you add a +1 at the position [243][233][233]. So in the end you would see in your example zero everywhere except at `[40,42,40] = 4`, `[255,255,255] = 1`, `[40,2,60] = 2`, `[9,9,0] = 1`, `[255,255,40] = 2` – Micka Feb 11 '14 at 10:00