如何以自己的色调显示颜色通道?

How to display a color channel in its own hue?

从图像中提取特定颜色通道时,EMGU CV中使用了以下代码:

EMGU.CV.UI.ImageBox originalImage;
EMGU.CV.UI.ImageBox bChannel;
...
Image<Bgra, Byte> image = new Image<Bgra, Byte>(filename);
originalImage = image;
bChannel = image[0]; // Index 0 is the blue channel (for BGRA).

不幸的是,分配给 ImageBox bChannel 的结果图像是灰度的,不是 蓝色。如何以自己的色调(在本例中为蓝色)显示图像?

最终我想提出一个 UI 类似于以下内容:


PS:根据 EMGU 是该库的包装器的推理,使用 "OpenCV" 标记额外标记此问题。 :)

在 post 提出我的问题后,我意识到我可以通过将所有其他通道值设置为 0(黑色)来隔离通道。这是我的代码:

Image<Bgra, Byte> img = new Image<Bgra, Byte>(filename);
Image<Bgra, Byte> blue = img.Copy();
Image<Bgra, Byte> green = img.Copy();
Image<Bgra, Byte> red = img.Copy();
Bgra tmp;
double saveGreen;
double saveRed;

for (int ii = 0; ii < img.Height; ii++)
{
    for (int jj = 0; jj < img.Width; jj++)
    {
        tmp = img[ii,jj];
        saveGreen = tmp.Green;
        saveRed = tmp.Red;

        // Blue
        tmp.Green = 0;
        tmp.Red = 0;
        blue[ii,jj] = tmp;

        // Green
        tmp.Green = saveGreen;
        tmp.Blue = 0;
        green[ii, jj] = tmp;

        // Red
        tmp.Red = saveRed;
        tmp.Green = 0;
        red[ii,jj] = tmp;
    }
}

imageBox1.Image = img;
imageBox2.Image = blue;
imageBox3.Image = green;
imageBox4.Image = red;

结果UI如下:

如果您认为生成的通道图像看起来不正确,或者如果您能想到一种无需访问每个像素的更快方法,请post回答或发表评论。

编辑 ED PLUNKETT 的评论 #1:

我实现了以下代码来设置通道颜色:

Bgra tmp;
Bgra save;

for (int ii = 0; ii < img.Height; ii++)
{
    for (int jj = 0; jj < img.Width; jj++)
    {
        tmp = img[ii,jj];
        save = tmp;

        // Red channel.

        if (tmp.Red == 255)
        {
            tmp.Blue = tmp.Green = 255;
        }
        else
            if (tmp.Red == 0)
            {
                tmp.Blue = tmp.Green = 0;
            }
            else
                if (tmp.Red < 128)
                {
                    tmp.Blue = tmp.Green = tmp.Red / 2;
                }

        red[ii, jj] = tmp;

        // Green channel.

        tmp = save;

        if (tmp.Green == 255)
        {
            tmp.Blue = tmp.Red = 255;
        }
        else
            if (tmp.Green == 0)
            {
                tmp.Blue = tmp.Red = 0;
            }
            else
                if (tmp.Green < 128)
                {
                    tmp.Blue = tmp.Red = tmp.Green / 2;
                }

        green[ii, jj] = tmp;

        // Blue channel.

        tmp = save;

        if (tmp.Blue == 255)
        {
            tmp.Green = tmp.Red = 255;
        }
        else
            if (tmp.Blue == 0)
            {
                tmp.Green = tmp.Red = 0;
            }
            else
                if (tmp.Blue < 128)
                {
                    tmp.Green = tmp.Red = tmp.Blue / 2;
                }

        blue[ii, jj] = tmp;
    }
}

此外,我使用了沙漠图像并四处移动通道,使顺序与示例图像中的 RGB 顺序相匹配。这是输出:

不太一样(红色通道太像原图了)但总体看起来更像沙漠图片示例中使用的拆分。

编辑 #2 ED PLUNKETT 的以下回答:

这是 pow = 1.5 的输出:

pow = 2.0 的输出:

pow = 2.5 的输出:

pow 的输出分别为红色 2.0、绿色 2.5 和蓝色 1.6:

这确实不是我的领域,但没有一个有适当理解的人对此感兴趣,所以不幸的是你现在暂时和我在一起。

有不止一种 "right" 方法可以做到这一点。您的第一次尝试将 "off hue" 通道设置为零,简单明了,毫无疑问具有隔离颜色通道的效果,但它与沙漠拱形示例的算法完全不同。视觉效果大不相同。

为简单起见,我只讨论 "isolating" 红色通道。相同的原则大致适用于其他两个(稍后会详细介绍)。

沙漠拱形示例所做的大致是保持整体亮度:原始图像中的白色像素最终成为结果中的白色像素;黑色像素也是如此。 R=128 的像素应该是红色的(依此类推,以获得平滑的曲线)。

怎么红?

为了我们这里的目的,当我们说一种颜色是 "red" 时,我们的意思是 G 和 B 通道相同,并且该值小于 R。也许少一点,也许少很多.当我们在低端接近黑色时,值向零收敛,而当我们在高端接近白色时,值向 255 收敛。在中间,它们有相当大的差异(如果有规范的 正确 amount,希望有比我更懂的人出现)。它们的差异越大,您的红色就会越饱和。曲线看起来像这里高度复杂的技术数据可视化:

下面的曲线描述了一个函数 f(R),其中 f(0)=0,f(255)=255,f(128) 等于小于 128 的某个数。如果你想着色要显红,最好少很多。

我数到十的时候会脱鞋,所以我把上面的图片通过电子邮件发给了一个朋友,他的朋友一直穿着他的。他建议使用以下 "power law" 公式:

x = 1.5
f(R) = 255 * Math.Pow(R/255, x);

...其中 x 是一个指数。如果x = 1.0,那么f(R)=R,这没什么用。从 1.52.5 的 x 值对我有用。您可以在右侧视觉效果中将 x 调整为零。

因此,如果您要隔离 R,

G = B = f(R)

如果你隔离 G,

R = B = f(G)

如果您要隔离 B,

R = G = f(B)

然而,实际上这三个通道并不是完全对称的。粗略地说,#00ff00 比#ff0000 亮,#ff0000 比#0000ff 亮。通过摆弄上述功能,我认为生成您的示例的算法可能会考虑到这一点。

如果我是你,我会根据你 "isolating" 的频道分别调整 x 以最好地近似原始图像。在一些快速摆弄中,我最终对 R 使用 x=2.0,对 G 使用 x=2.5,对 B 使用 x=1.6。

我很确定它仍然是错误的曲线,但这是正确的总体思路。取决于你有多接近钉这个东西,你可能想要 Google "power law" 并尝试不同的曲线函数。