c - 逐像素模糊 c 中的图像 - 特殊情况
问题描述
我正在开发一个程序,它会稍微模糊 c 中的图像。
知道我需要 8 个周围像素和所选像素的平均值和 rgb 值来更改该像素的颜色,我将它们加在一起并取平均值。
我知道我实现这一点的方式并不是最有效的方式,所以如果有任何关于如何简化这一点的建议,请告诉我。
我计划在最后的第三个 for 循环中复制tempimage
回image
。
该结构RGBTRIPLE
包含一个像素的 rgb 值。
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
我现在的问题是处理特殊情况,例如图像的边缘或侧面的像素。
当所选像素未被 9 个像素包围时,如何获取周围像素的值?
到目前为止,这是我的代码:
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// copy all values to temporary image
RGBTRIPLE tempimage[height][width];
int avgRed = 0;
int avgGreen = 0;
int avgBlue = 0;
//copy pixels to temp image
for ( int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{
tempimage[x][y] = image[x][y];
}
}
//get average of surrounding pixels
for ( int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
//TODO: edge check
//surrounding pixels
avgRed = round(((float)(image[i][j].rgbtRed
+ image[i][j - 1].rgbtRed + image[i][j + 1].rgbtRed
+ image[i - 1][j].rgbtRed + image[i - 1][j - 1].rgbtRed
+ image[i - 1][j + 1].rgbtRed + image[i + 1][j].rgbtRed
+ image[i + 1][j - 1].rgbtRed + image[i + 1][j + 1].rgbtRed)) / 9);
avgGreen = round(((float)(image[i][j].rgbtGreen
+ image[i][j - 1].rgbtGreen + image[i][j + 1].rgbtGreen
+ image[i - 1][j].rgbtGreen + image[i - 1][j - 1].rgbtGreen
+ image[i - 1][j + 1].rgbtGreen + image[i + 1][j].rgbtGreen
+ image[i + 1][j - 1].rgbtGreen + image[i + 1][j + 1].rgbtGreen)) / 9);
avgBlue = round(((float)(image[i][j].rgbtBlue
+ image[i][j - 1].rgbtBlue + image[i][j + 1].rgbtBlue
+ image[i - 1][j].rgbtBlue + image[i - 1][j - 1].rgbtBlue
+ image[i - 1][j + 1].rgbtBlue + image[i + 1][j].rgbtBlue
+ image[i + 1][j - 1].rgbtBlue + image[i + 1][j + 1].rgbtBlue)) / 9);
tempimage[i][j].rgbtRed = avgRed;
tempimage[i][j].rgbtGreen = avgGreen;
tempimage[i][j].rgbtBlue = avgBlue;
}
}
//TODO: for loop to copy tempimage back to image here
return;
}
解决方案
在像您这样的算法中,有多种方法可以处理“边缘”情况。如果它位于相关边缘,则下面的代码使用当前的“行”或“列”(而不是它的上方/下方或左/右):
for ( int i = 0; i < height; i++)
{
// Edge check (A for 'above' index and B for 'below'):
int A = i - 1; if (A < 0) A = 0;
int B = i + 1; if (B > height - 1) B = height - 1;
for (int j = 0; j < width; j++)
{
// Edge check (L = 'left of', R = 'right of'):
int L = j - 1; if (L < 0) L = 0;
int R = j + 1; if (R > width - 1) R = width - 1;
// Then change all your 'i-1'|'i+i'|'j-i'|j+1' indexes to A|B|L|R:
avgRed = round(((float)(image[i][j].rgbtRed
+ image[i][L].rgbtRed + image[i][R].rgbtRed
+ image[A][j].rgbtRed + image[A][L].rgbtRed
+ image[A][R].rgbtRed + image[B][j].rgbtRed
+ image[B][L].rgbtRed + image[B][R].rgbtRed)) / 9);
// ... and similarly for green and blue ...
顺便说一句,我注意到您的像素索引为 image[column][row] (= column-major order)。按照惯例,C
二维C++
数组以相反的方式定义,如 image[row][column](= row-major order);但是,只要您确定这是您所拥有的,那就没问题!
推荐阅读
- progressive-web-apps - 为什么我的文件没有通过 Service Broker 缓存?
- node.js - React 不显示从 axios 返回的数组的所有值
- prolog - Prolog检查列表是否包含另一个列表元素的2倍
- php - 如何避免在 YII2 查询链接中覆盖
- python - 将 MNIST 数据从 numpy 数组转换为原始 ubyte 数据
- api - 带有翻译器消息的 Api 平台自定义异常
- html - 如何制作包含合并单元格的 HTML 表格
- typescript - 找不到名称“文档”。您需要更改目标库吗?尝试更改 `lib` 编译器选项以包含 'dom'.ts(2584)
- ios - 如何在 Apple Silicon ('M1') 上构建 Google Analytics SDK,使其在 Xcode Simulator 中运行?
- javascript - 如何使用传单从地图上删除标记?