我正在尝试使用 C++ 和 opencv 对图像的色彩平衡进行评分。
要做到这一点,最简单的方法是计算每种颜色的像素数,然后查看其中一种颜色是否更普遍。
我认为我可能应该使用 calcHist 和拆分功能,我可以将图像拆分为 R、G 和 B 直方图。但是我不确定下一步该怎么做。我可能可以遍历所有的 bin,看看里面有多少像素,但这似乎需要很多工作(我目前使用 256 个 bin)。
有没有更快的方法来计算颜色范围内的像素?另外,我不确定如果白色或黑色是更流行的颜色,它会如何工作?
最佳答案
此链接描述了自动色彩平衡算法 http://web.stanford.edu/~sujason/ColorBalancing/simplestcb.html
对于 C++ 代码,您可以引用此链接:https://www.morethantechnical.com/2015/01/14/simplest-color-balance-with-opencv-wcode/
/// perform the Simplest Color Balancing algorithm
void SimplestCB(Mat& in, Mat& out, float percent) {
assert(in.channels() == 3);
assert(percent > 0 && percent < 100);
float half_percent = percent / 200.0f;
vector<Mat> tmpsplit; split(in,tmpsplit);
for(int i=0;i<3;i++) {
//find the low and high precentile values (based on the input percentile)
Mat flat; tmpsplit[i].reshape(1,1).copyTo(flat);
cv::sort(flat,flat,CV_SORT_EVERY_ROW + CV_SORT_ASCENDING);
int lowval = flat.at<uchar>(cvFloor(((float)flat.cols) * half_percent));
int highval = flat.at<uchar>(cvCeil(((float)flat.cols) * (1.0 - half_percent)));
cout << lowval << " " << highval << endl;
//saturate below the low percentile and above the high percentile
tmpsplit[i].setTo(lowval,tmpsplit[i] < lowval);
tmpsplit[i].setTo(highval,tmpsplit[i] > highval);
//scale the channel
normalize(tmpsplit[i],tmpsplit[i],0,255,NORM_MINMAX);
}
merge(tmpsplit,out);
}
// Usage example
void main() {
Mat tmp,im = imread("lily.png");
SimplestCB(im,tmp,1);
imshow("orig",im);
imshow("balanced",tmp);
waitKey(0);
return;
}
关于c++ - 使用 C++ 和 opencv 在图像中进行色彩平衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29166804/