gpt4 book ai didi

c++ - OpenCV:实验室颜色量化为预定义颜色

转载 作者:行者123 更新时间:2023-11-28 04:56:52 35 4
gpt4 key购买 nike

我尝试使用以下函数将我的图像颜色减少为一些预定义的颜色:

void quantize_img(cv::Mat &lab_img, std::vector<cv::Scalar> &lab_colors) {
float min_dist, dist;
int min_idx;
for (int i = 0; i < lab_img.rows*lab_img.cols * 3; i += lab_img.cols * 3) {
for (int j = 0; j < lab_img.cols * 3; j += 3) {
min_dist = FLT_MAX;
uchar &l = *(lab_img.data + i + j + 0);
uchar &a = *(lab_img.data + i + j + 1);
uchar &b = *(lab_img.data + i + j + 2);
for (int k = 0; k < lab_colors.size(); k++) {
double &lc = lab_colors[k](0);
double &ac = lab_colors[k](1);
double &bc = lab_colors[k](2);
dist = (l - lc)*(l - lc)+(a - ac)*(a - ac)+(b - bc)*(b - bc);
if (min_dist > dist) {
min_dist = dist;
min_idx = k;
}
}
l = lab_colors[min_idx](0);
a = lab_colors[min_idx](1);
b = lab_colors[min_idx](2);
}
}
}

但是它似乎不能正常工作!例如,以下输入的输出看起来很棒!

if (!(src = imread("im0.png")).data)
return -1;
cvtColor(src, lab, COLOR_BGR2Lab);
std::vector<cv::Scalar> lab_color_plate_({
Scalar(100, 0 , 0), //white
Scalar(50 , 0 , 0), //gray
Scalar(0 , 0 , 0), //black
Scalar(50 , 127, 127), //red
Scalar(50 ,-128, 127), //green
Scalar(50 , 127,-128), //violet
Scalar(50 ,-128,-128), //blue
Scalar(68 , 46 , 75), //orange
Scalar(100,-16 , 93) //yellow
});
//convert from conventional Lab to OpenCV Lab
for (int k = 0; k < lab_color_plate_.size(); k++) {
lab_color_plate_[k](0) *= 255.0 / 100.0;
lab_color_plate_[k](1) += 128;
lab_color_plate_[k](2) += 128;
}
quantize_img(lab, lab_color_plate_);
cvtColor(lab, lab, CV_Lab2BGR);
imwrite("im0_lab.png", lab);

输入图像: Input image

输出图像 enter image description here

谁能解释一下问题出在哪里?

最佳答案

检查您的算法后,我注意到该算法 100% 正确,问题出在您的色彩空间....让我们选择一种“错误”更改的颜色,例如树上的绿色。

使用 GIMP 中的颜色选择器工具,它会告诉您至少使用的绿色之一是 RGB (111, 139, 80)。将其转换为 LAB 时,您会得到 (54.4, -20.7, 28.3)。到绿色的距离是(根据你的公式) 21274.34 ,而灰色的距离是 1248.74 ...所以它会选择灰色而不是绿色,即使它是绿色。

LAB中的很多值都可以产生绿色值。您可以在 this webpage 中的颜色范围内对其进行测试.我建议您使用 HSV 或 HSL 并仅比较 H 值,即 Hue。其他值只改变绿色的色调,但色调中的一个小范围决定它是绿色的。这可能会给你更准确的结果。

作为改进代码的一些建议,请使用 Vec3b 和 cv::Mat 函数,如下所示:

for (int i = 0; i < lab_img.rows; ++i) {
for (int j = 0; j < lab_img.cols; ++j) {
Vec3b pixel = lab_img.at<Vec3b>(i,j);
}
}

这样代码可读性更强,一些检查在 Debug模式下完成。

另一种方法是做一个循环,因为你不关心索引

 auto currentData = reinterpret_cast<Vec3b*>(lab_img.data); 
for (size_t i = 0; i < lab_img.rows*lab_img.cols; i++)
{
auto& pixel = currentData[i];
}

这种方式也比较好。最后一部分只是一个建议,您当前的代码没有任何问题,只是更难被外部观众阅读理解。

关于c++ - OpenCV:实验室颜色量化为预定义颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46956789/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com