1

我想制作具有不同窗口大小(由用户确定)的马赛克照片。这就像代码的初稿,但我在获取像素和计算平均值时遇到了问题。然后将平均值放在每个像素中并继续到最后。即使我将它们转换为不同类型时也会出错:(其他部分也制造灰度图像) 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.rgbGreen, color.rgbBlue);
                newcolor.rgbRed   = (BYTE)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);

                m_pImage->SetPixelColor(x, y, newcolor);
            }
        }
    }
}
 } '''

谁能帮我理解这个问题?

4

1 回答 1

1

我认为你在这里混合了空间、光谱和时间平均值。

空间平均值

这是计算一个区域的像素平均值的操作。

你必须计算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, avg, 1.0f));
            }
        }

请注意,使用平均值将非线性 RGB(通常称为 sRGB)转换为亮度对于 RGB 到灰度转换来说是一个糟糕的公式。您应该阅读有关 RGB 到 Lab* 的转换(您只对L部分感兴趣)或至少 RGB 到 YUV(您只对Y部分感兴趣)。

如果您的问题是关于调整输入图片的大小,那么您没有使用适当的算法,您想要的就是重新采样

于 2020-09-23T12:55:14.000 回答