我在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;
}
提前谢谢))
答案 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 >= 0
和max <= 255
以及min < max
。
首先你必须确保亮度在最小...最大范围内,否则你的结果将超过0 ... 255的范围。你也可以限制输出的范围,但无论如何你必须进行范围检查。
然后从亮度中减去min。现在,您的值介于0和(最大 - 最小)之间。除以(max - min),得到0到1之间的值。将结果乘以255,得到所需范围0 ... 255的值。
此外,您必须意识到您正在执行整数运算。因此先乘以255然后再除。如果从分割开始,则得到0或1作为中间结果(因为整数运算不产生小数,最终结果将为0或255,所有灰色调都会丢失。
答案 1 :(得分:0)
您看到的效果称为banding
或posterisation
。这是通过对未以足够的位深度采样的数据进行对比度延伸而引起的。由于您只有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
他们看起来像这样:
如果我现在将它们拉伸到0-255的整个范围,您将立即看到8位版本的条带效果,以及16位版本的平滑度 - 顺便提一下,这是使用的原因相机上的RAW格式(12-14位)而不是拍摄8位JPEG:
convert gradient8.png -auto-level out8.png
convert gradient16.png -auto-level out16.png
我提到使用噪音来重新调整条纹效果的可见性,你可以使用这样的技术来做到这一点:
convert out8.png -attenuate 0.3 +noise gaussian out.png
它会给你一个不太明显的效果,有点类似于胶片颗粒:
我不确定你到底想要做什么,但是如果你只是想在0-255的整个范围内将亮度等级从127-255分散,你可以在命令行中这样做,就像这样:
convert orig.png -level 50%,100% whites.png
同样,如果您想要0-17范围内的亮度级别分布在0-255范围内,您可以
convert orig.png -level 0,6.66667% blacks.png