我正试图在c中制作一个简单的模糊效果。我有一个512 * 512 RGB像素阵列加载的图像,我使用3x3内核来模糊该图像
这是内核
float matrix[9] = {1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f};
这是执行bluring的代码
void useBlur(){
for(int i = 0; i < ARRAY_SIZE; i++){
float r = 0;
float g = 0;
float b = 0;
int m, n;
for(int y = -1, m = 0; y <= 1; y++, m++){
for(int z = -1, n = 0; z <= 1; z++, n++){
r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n];
g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n];
b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n];
}
}
image[i].r = r;
image[i].g = g;
image[i].b = b;
}
}
我不确定该代码有什么问题,但它产生了结果:
为什么颜色错了?以及如何解决它?
编辑: 固定矩阵[7]从9.0 / 9.0到1.0 / 9.0并上传新图像
答案 0 :(得分:3)
我尝试了一些更改的代码,我的图像是BGRA,我使用opencv作为我的图像容器,但代码的结构是相同的,并且它完美地工作。
for (int i = 2*image.cols; i < image.rows*image.cols-2*image.cols; i++)
{
float r = 0;
float g = 0;
float b = 0;
for (int y = -1; y <=1; y++)
{
for (int z = -1; z <=1; z++)
{
b += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(0)*(1.0/9);
g += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(1)*(1.0/9);
r += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(2)*(1.0/9);
}
}
image.at<cv::Vec4b>(i)(0) = b;
image.at<cv::Vec4b>(i)(1) = g;
image.at<cv::Vec4b>(i)(2) = r;
}
我认为这意味着问题要么不在您发布的代码中,要么以某种方式opencv cv :: Mat类处理您的图像容器不是。显而易见的是,您似乎在代码末尾隐式地从float转换为uchar。你能测试在你的图像上运行这个循环但是没有修改它吗?它可能看起来像这样,或任何其他方式。这很难看,但很快就转换了。
void useBlur(){
for(int i = 0; i < ARRAY_SIZE; i++){
float r = 0;
float g = 0;
float b = 0;
int m, n;
for(int y = -1, m = 0; y <= 1; y++, m++){
for(int z = -1, n = 0; z <= 1; z++, n++){
if(y == 0 && z == 0)
{
r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n]*9;
g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n]*9;
b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n]*9;
}
}
}
image[i].r = r;
image[i].g = g;
image[i].b = b;
}
}
理论上,当你这样做时,图像没有任何变化,所以如果图像正在改变,那是因为一些转换错误。我承认这个理论不太可能,但你的代码结构似乎很合理,所以我不知道还有什么建议。