OpenCV:如何查找图像中使用最少的颜色

时间:2018-07-18 09:27:56

标签: opencv

寻找图像中使用最少的颜色的算法是什么?我是opencv的新手。

阅读回复后的代码。 我该如何改善?还有如何检查它是否适用于“最少使用的颜色”。

int main(int argc, char* argv[]) {
// Load the file
char* filename = argv[1];
cv::Mat matImage = cv::imread(filename);

if(!matImage.data) {
    printf("Unable to open the file: %s\n", filename);
    return 1;
}
const int width = matImage.cols;
const int height = matImage.rows;
printf("\n height -> %d , width -> %d\n",height,width);
map<string,int> mymap;
int c = 1;
for(int y=0;y<height;y++) {
    cv::Vec3b* ptr = matImage.ptr<cv::Vec3b>(y);
    for(int x=0;x<width;x++) {
        cv::Vec3b color = ptr[x];
        char buff[16];
        sprintf(buff,"#%02x%02x%02x",color[0],color[1],color[2]);
        string s(buff); 
        if(mymap.find(s) == mymap.end()){
            mymap[s] = 1;
        }
        else 
            mymap[s] = mymap[s] + 1;
    }
}
cout<<"color count = "<<mymap.size()<<endl;
int max = 0;
int min = mymap.size(); 
string strmax,strmin;
for (std::map<string,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it){
        if(it->second > max)
        {
            max = it->second;
            strmax = it->first;
        }
        if(it->second < min)
        {
            min = it->second;
            strmin = it->first;
        }
    }
    cout<<"most used color -> "<<strmax<<" count -> "<<max<<endl;
    cout<<"least used color -> "<<strmin<<" count -> "<<min<<endl;
return 0;
}

2 个答案:

答案 0 :(得分:0)

通过openCV中的以下过程可以轻松检测图像中存在的红色,绿色和蓝色的原色。

split((Image),channels);  
Mat red, blue, green;

inRange(channels[0], Scalar(50), Scalar(255), blue); // blue
inRange(channels[1], Scalar(50), Scalar(255), green); // green
inRange(channels[2], Scalar(50), Scalar(255), red); // red

double image_size = abs((Image).cols * (Image).rows);  // Total no of pixels in the image
double red_percent = ((double) cv::countNonZero(red))/image_size;
double blue_percent = ((double) cv::countNonZero(green))/image_size;
double green_percent = ((double) cv::countNonZero(blue))/image_size;

答案 1 :(得分:0)

我想您可以制作一个由(R<<16)||(G<<8)||B索引的1600万个条目数组,然后将图像中的所有像素传递通过,从而增加相应的条目。然后遍历数组以找到该数组中最小的非零条目。

这可能只需要大约64MB的RAM左右,而在多GB的计算机上则没什么。

自您添加代码以来已更新

您的代码看起来非常明智。作为一项检查,您可以使用 ImageMagick 来获取颜色的出现频率,大多数Linux发行版以及macOS和Windows上都可以使用。

在终端中使用此命令可以查看10种最不经常出现的颜色:

convert YourImage.png -define histogram:unique-colors=true -format %c histogram:info:- | sort -n | head -10

示例输出

    35: (104, 89,206) #6859CE srgb(104,89,206)
    39: (109, 83, 47) #6D532F srgb(109,83,47)
    51: (103, 73,135) #674987 srgb(103,73,135)
    59: (214,120,103) #D67867 srgb(214,120,103)
    59: (223,224,228) #DFE0E4 srgb(223,224,228)
    63: (202,115,117) #CA7375 srgb(202,115,117)
    67: (205,150, 72) #CD9648 srgb(205,150,72)
    71: (230,164, 96) #E6A460 srgb(230,164,96)
    75: (173,149, 83) #AD9553 srgb(173,149,83)
    77: (182,134, 55) #B68637 srgb(182,134,55)

所以这意味着#6859CE是我的示例图像中出现频率最低的颜色,总计数为35像素。


如果您安装 ImageMagick v7 +,该命令将变为:

magick YourImage.png -define histogram:unique-colors=true -format %c histogram:info:- | sort -n | head -10