在这里,我试图对RGB图像进行标准化。
这是我的代码。
cv::Mat channels[3], normalize_rgb;
split(image, channels);
for (int i = 0; i < image.size().height; i++)
{
for (int j = 0; j < image.size().width; j++)
{
int b = (int)(image).at<cv::Vec3b>(i, j)[0];
int g = (int)(image).at<cv::Vec3b>(i, j)[1];
int r = (int)(image).at<cv::Vec3b>(i, j)[2];
double sum = b + g + r;
double bnorm = b / sum * 255;
double gnorm = g / sum * 255;
double rnorm = r / sum * 255;
channels[0].at<uchar>(i, j) = bnorm;
channels[1].at<uchar>(i, j) = gnorm;
channels[2].at<uchar>(i, j) = rnorm;
}
}
merge(channels, 3, normalize_rgb);
normalize = normalize_rgb.clone();
问题:归一化后,r,g,b值给出了非常小的值,变为0.因此我得到了黑色图像。
任何人都可以帮我解决问题。谢谢
答案 0 :(得分:2)
首先将图片更改为double
。它是黑色的,因为当你将int
除以int
时,你会得到零。然后你试图设置uchar = double
这是完全错误的。
尝试:
double bnorm = double (b) / sum * 255;
答案 1 :(得分:0)
您需要将double bnorm = b * k;
double gnorm = g * k;
double rnorm = r * k;
除以像素数。
在1000x1000图像中,您希望除以平均值,而不是平均值的一百万倍。
请注意,除以平均值可能会给出大于255的值(高于平均值的值),因此在缩放后需要进行钳位。可能更好的解决方案是将平均值变为128,而不是255
k
其中double average = sum / (image.size().height*image.size().width);
double k = 127.0 / average;
每个图像计算一次为
{{1}}
但请注意,这仍然会在输出中产生高于255的值。
如果你想拉伸,你需要用最大值进行标准化,而不是平均值,在这种情况下不需要夹紧。
答案 2 :(得分:0)
我找到了一个与RGB Normalization相关的链接,文章中有一个数学列表。
实际上,你需要划分一个var total,每个total只是每个像素的总和,而不是整个图像(width()* height())。也许你应该试试这个:
for (int i = 0; i < image.size().height; i++)
{
for (int j = 0; j < image.size().width; j++)
{
int b = (int)(image).at<cv::Vec3b>(i, j)[0];
int g = (int)(image).at<cv::Vec3b>(i, j)[1];
int r = (int)(image).at<cv::Vec3b>(i, j)[2];
int sum = b + g + r;
double bnorm = b / sum * 255;
double gnorm = g / sum * 255;
double rnorm = r / sum * 255;
channels[0].at<uchar>(i, j) = bnorm;
channels[1].at<uchar>(i, j) = gnorm;
channels[2].at<uchar>(i, j) = rnorm;
}
}