问题描述
我想制作一个窗口大小不同的马赛克照片(由用户确定)。这就像代码的初稿一样,但是我在获取像素和计算平均值时遇到了问题。然后将平均值放在每个像素中并继续到结尾。甚至我在将它们转换为不同类型时都出错:(另外,另一部分制造灰度图像) ps:很抱歉,我正处于学习图像处理的第一步。
''' void CImageProcessingDoc::OnProcessMosaic()
{
if (m_pImage) {
DlgMosaicoption dlg;
if (dlg.DoModal() == IDOK) {
DWORD dwWindowSize = dlg.m_dwWindowSize;
DWORD width = m_pImage->GetWidth();
DWORD height = m_pImage->GetHeight();
RGBQUAD color;
RGBQUAD newcolor;
float X_step = width / dwWindowSize;
float Y_step = height / dwWindowSize;
int avg,pixel;
for (DWORD y = 0; y < dwWindowSize; y++) {
for (DWORD x = 0; x < dwWindowSize; x++) {
color = m_pImage->GetPixelColor(x,y);
(RGBQUAD) pixel = m_pImage->GetPixelColor(x,y);
avR += (int)(color.red(pixel);
avG += (int)(color.green(pixel);
avB += (int)(color.blue(pixel);
newcolor.rgbBlue = (BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue);
newcolor.rgbGreen = (BYTE)RGB2GRAY(color.rgbRed,color.rgbBlue);
newcolor.rgbRed = (BYTE)RGB2GRAY(color.rgbRed,color.rgbBlue);
m_pImage->SetPixelColor(x,y,newcolor);
}
}
}
}
} '''
有人可以帮我理解这个问题吗?
解决方法
我认为您在这里混合了空间,频谱和时间平均值。
空间平均值
这是计算区域平均像素的操作。
您必须计算eR = 1/N * (P0.R + P1.R + P2.R + P3.R + ...)
,eG = 1/N * (P0.G + P1.G + ...)
,eB = 1/N * (P0.B + P1.B + ...)
您将获得与输入图片一样多的颜色的像素,但是在有限的空间频率下,这样计算的图片将显得模糊,没有任何细节
频谱平均值
这是计算每个像素的成分(光谱)平均值的操作。
您必须计算e = 1/3 * (P0.R + P0.G + P0.B)
您将获得一张单色图片,其空间频率与原始图片完全相同。
时间平均
虽然您没有谈论它,但仅供参考。想法是计算时间序列中N个图片的每个像素和每个分量的平均值
这给出了一种运动模糊的图片。
答案
如果我正确理解了您的问题,则希望光谱平均值将RGB转换为grey = (R+G+B)/3
所取的平均灰度值。
因此,像素循环应如下所示:
for (DWORD y = 0; y < dwWindowSize; y++) {
for (DWORD x = 0; x < dwWindowSize; x++) {
color = m_pImage->GetPixelColor(x,y);
float avg = (color.rgbRed + color.rgbGreen + color.rgbBlue) / 3.f;
m_pImage->SetPixelColor(x,y,RGBQUAD(avg,avg,1.0f));
}
}
请注意,使用平均值将非线性RGB(通常称为sRGB)转换为亮度是将RGB转换为灰度的较差公式。您应该阅读有关RGB到Lab *的转换(仅对L
部分感兴趣)或至少从RGB到YUV的转换(仅对Y
部分感兴趣)。
如果您的问题是要调整输入图片的大小,那么您就没有使用适当的算法,您想要的就是重采样。