2014-12-13 75 views
0

我在C#中编写程序,但希望C++和C#在背景中完全相同。 我想要什么 - 采取灰度图像和单独的颜色超过127和17以分离图像。如果我只是得到“白”的颜色和编程方式从范围(127-255)至(0-255)舒展他们像ImageMagick - 为灰度图像设置水平

// 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,...不存在。

即原始图像具有α: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; 
} 

thankы))

+0

我觉得你的问题很难理解。如果你从一个1像素高,256像素宽的图像开始,第一个像素为0,然后是1,2,3 ... 255,那么将会有多少输出图像以及每个图像在哪个图像中? – 2014-12-16 19:57:30

+0

@Mark Setchell,会有两个图像。如果中间是“中间灰色”,则:首先是“0,0,2,2,4,4 ...... 255,255”。下一个 - '0,0,2,2,4,4,... 255,255'。如果在255的1/4(第一季度与其他季度之间)中的“中灰度”,则:首先是“0,0,0,0,4,4,4,4 ...... 255,255”。接下来是'0,1,2,2,4,5,6,6,8,... 254,255'。因为尝试将0..63范围拉伸到0..255。 – user3444737 2014-12-16 20:29:20

回答

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 <= 255min < max

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

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

此外,您还必须了解你正在执行整数算术。因此,先乘以255,然后除。如果以分割开始,则得到0或1作为中间结果(因为整数算术不会产生小数,并且最终结果将为0或255,并且所有灰色都会丢失)

+0

是的,你说得对。值必须移动到零电平:'类节目 \t { \t \t静态INT计算(INT VAL,INT分钟,INT最大值) \t \t { \t \t \t回报(INT)(((浮动)VAL - 分钟)/(max - min)* max); \t \t} \t \t静态无效的主要(字符串[]参数) \t \t { \t \t \t INT分钟= 127,最大= 255; \t \t \t int bgn = 127,mdl = 200,end = 255; (“Expected 0,Got - ”+ Calc(bgn,min,max).ToString()); (“预期〜150,得到 - ”+ Calc(mdl,min,max).ToString()); Debug.WriteLine(“Expected 255,Got - ”+ Calc(end,min,max).ToString()); \t \t} \t}''预期0,GOT - 0 预期〜150,GOT - 145 预期255,GOT - 255' – user3444737 2014-12-13 16:10:18

+0

但是,这不是其中i是栈(( – user3444737 2014-12-13 16:16:38

+0

似乎有一种方法这样做'无效BrightnessContrast(百分比亮度,百分比对比);'。还有一个'WritablePixelCollection GetWritablePixels();'方法返回像素,你可以改变自己。 – 2014-12-13 18:46:09

0

您看到的效果是称为bandingposterisation这是因为对比度不足以获得足够的位深度,因为只有8位数据,所以只有255个灰度级,如果您将50个级别拉伸到100-150在255个级别的范围内,直方图会出现5级左右的空白,解决办法是获得16位数据,或者在对比度上做较小的改变。是一名摄影师,对此更感兴趣e的图像美学比它的科学准确性,你可以添加少量的随机噪声伪装和“涂抹”的条带...

有一个很好的描述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位版本的条纹的效果,并且smoo

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

enter image description here enter image description here

:顺便说一下,是你的相机使用RAW格式(12-14位),而不是拍摄的8位JPEG文件的原因 - 的16位版本thness我提到了使用噪音redue的条纹效果的可视性,你可以做,使用这样的技术:

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

,让你不那么显着的效果,有点类似胶片颗粒:

enter image description here

我不能肯定到底是什么你正在尝试做的,但如果你只是想从127-255在整个0-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