【问题标题】:Make a mosaic image (bitmap format)制作马赛克图像(位图格式)
【发布时间】:2020-09-23 09:47:27
【问题描述】:

我想制作具有不同窗口大小(由用户确定)的马赛克照片。这就像代码的初稿,但我在获取像素和计算平均值时遇到了问题。然后将平均值放在每个像素中并继续到最后。即使我将它们转换为不同类型时也会出错:(其他部分也制造了灰度图像) p.s:抱歉,我刚刚开始学习图像处理。

''' 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);
            }
        }
    }
}
 } '''

谁能帮我理解这个问题?

【问题讨论】:

  • 你必须初始化你的变量,否则它们的初始值可以是任何东西。结果,您会得到不正确的结果。例如。 int avg = 0; int pixel = 0;
  • @vahancho 显然是好的建议,但不是这里的问题
  • 请提供更多信息。您期望什么以及您的代码的结果是什么?

标签: c++ visual-studio image-processing bitmap mosaic


【解决方案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 部分感兴趣)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多