ImageMagick - 设置灰度图像的级别

时间:2014-12-13 13:13:29

标签: c# c++ imagemagick magick.net

我在C#中编写程序,但希望C ++和C#在后台完全相同。 我想要的 - 采用灰度图像和127或17以下的单独颜色来分离图像。如果我只是得到“白色”颜色并以编程方式将它们从范围(127-255)拉伸到(0-255),如

// pseudocode
int min = 127, max = 255;
for(int x; x< width; x++)
    pixels[x] = pixels[x]/(max-min) * max;

然后这里将不是平滑间隔..我的意思是,127转换为0但128转换为2并且颜色1,3,5,...不存在。

这是带有alpha的原始图片:image original

这是带有“提取的白色”的图像:image original

这是“提取黑色”的图像:snorgg.ru/patchwork/tst_black.png。

我不清楚它是如何实现的,所以exampe代码会像:

{
   im.MagickImage image = new im.MagickImage("c:/55/11.png");
   im.MagickImage imageWhite = ExtractWhite(image);
   im.MagickImage imageBlack = ExtractBlack(image);
}

....  

public static im.MagickImage ExtractWhite(im.MagickImage  img){

   im.MagickImage result = new im.MagickImage(img);

   ?????
   ?????

   return result;
}

提前谢谢))

2 个答案:

答案 0 :(得分:0)

我认为你的计算错了。您将输入范围与输出范围混淆。输入范围从最小值到最大值,输出范围从0到255.输入最大值等于输出最大值(255)是巧合。

如果要将min ... max(=输入范围)范围内的值拉伸到0 ... 255(=输出范围),请计算此

int brightness = pixel[x];
if (brightness <= min) {
    pixel[x] = 0;
} else if (brightness >= max) {
    pixel[x] = 255;
} else {
    pixel[x] = 255 * (brightness - min) / (max - min);
}

min >= 0max <= 255以及min < max

首先你必须确保亮度在最小...最大范围内,否则你的结果将超过0 ... 255的范围。你也可以限制输出的范围,但无论如何你必须进行范围检查。

然后从亮度中减去min。现在,您的值介于0和(最大 - 最小)之间。除以(max - min),得到0到1之间的值。将结果乘以255,得到所需范围0 ... 255的值。

此外,您必须意识到您正在执行整数运算。因此先乘以255然后再除。如果从分割开始,则得到0或1作为中间结果(因为整数运算不产生小数,最终结果将为0或255,所有灰色调都会丢失。

答案 1 :(得分:0)

您看到的效果称为bandingposterisation。这是通过对未以足够的位深度采样的数据进行对比度延伸而引起的。由于您只有8位数据,因此只有255个灰度级。如果在255个级别的范围内将50个级别拉伸到100-150之间,则直方图中的间隙将大约为5个级别。解决方案是要么获得16位数据,要么在对比度上做出较小的改变。

或者,如果像我一样,你是一名摄影师,对图像的美学比对它的科学准确性更感兴趣,你可以添加少量的随机噪音来掩盖和涂抹&#34;绑扎......

有一个很好的描述here

我还可以向您展示ImageMagick的示例,首先我们创建两个灰度渐变(渐变),一个8位和一个16位,两者的亮度级别从100到150不等,如下所示:

convert -depth 8 -size 100x500 gradient:"rgb(100,100,100)-rgb(150,150,150)" -rotate 90 gradient8.png

convert -depth 16 -size 100x500 gradient:"rgb(100,100,100)-rgb(150,150,150)" -rotate 90 gradient16.png

他们看起来像这样:

enter image description here enter image description here

如果我现在将它们拉伸到0-255的整个范围,您将立即看到8位版本的条带效果,以及16位版本的平滑度 - 顺便提一下,这是使用的原因相机上的RAW格式(12-14位)而不是拍摄8位JPEG:

convert gradient8.png  -auto-level out8.png
convert gradient16.png -auto-level out16.png

enter image description here enter image description here

我提到使用噪音来重新调整条纹效果的可见性,你可以使用这样的技术来做到这一点:

convert out8.png -attenuate 0.3 +noise gaussian  out.png

它会给你一个不太明显的效果,有点类似于胶片颗粒:

enter image description here

我不确定你到底想要做什么,但是如果你只是想在0-255的整个范围内将亮度等级从127-255分散,你可以在命令行中这样做,就像这样:

convert orig.png -level 50%,100% whites.png

enter image description here

同样,如果您想要0-17范围内的亮度级别分布在0-255范围内,您可以

convert orig.png -level 0,6.66667% blacks.png

enter image description here