在c ++中将像素值转换为图像

时间:2014-02-28 08:45:51

标签: image image-processing

我有一个有2列的文件。第一列具有所有像素位置,第二列具有与该像素对应的值。该像素值非常小(E-9阶)。

我想创建一个大小为512x512的图像,其中像素位置在文本文件中以相同颜色着色。所以,像素值并不重要。

请告诉我如何在c ++中执行此操作以及需要哪些其他库。

输入文件

872 4.19078e-010
1000 4.59096e-009
1127 1.2677e-010
1128 8.78192e-010
1255 1.59879e-009
7233 9.87113e-010
7234 2.1458e-009
8130 8.00793e-007
8131 9.02571e-007
8258 8.23907e-007
8259 6.44226e-007
8264 1.68967e-009
8265 1.9245e-009
8385 7.74323e-010
8386 2.10707e-009
8387 2.77237e-009
8388 2.12874e-009
8513 2.81146e-010
8516 1.08573e-008

1 个答案:

答案 0 :(得分:2)

我建议您查看netpbm包,特别是PGM格式 - Portable Greymap here。在没有库的情况下用C语言编写非常容易,因为它是纯ASCII,适用于小文件并且易于处理。基本上,您的文件将以PGM格式显示:

P2
512 512
255
0 0 0 0 0 0 0 0 0 0 0 0 0 0 .... 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 .... 0
0 0 0 0 0 0 0 0 0 255 .... 0 0 0 0 0 0

P2只是说它是灰度和ASCII。 512 512是尺寸,255是最大像素亮度。然后,您的图像有512条扫描线,每条扫描线有512个像素值,用空格分隔。黑色像素为零。白色像素为255.因此上例中的255是您在第二条扫描线末端附近的像素数872。

拥有PGM / PBM文件后,您可以使用ImageMagick轻松将其转换为其他任何文件,甚至可以将其直接读入许多应用程序 - 例如Photoshop中。

有一个例子here,从第51行开始,看一下P5格式的例子,它类似于P2格式,但是用二进制代替ASCII格式。

以下是我的意见: enter image description here

稍后添加

为了好玩,我使用awk转换了您的数据,而根本不需要任何C编程。这是一个单行(为了便于阅读,分为3行):

awk 'BEGIN {print "P5\n512 512\n255\n";for(i=0;i<512*512;i++)p[i]=0}
     {p[$1]=255}
     END {for(i=0;i<512*512;i++)printf "%c",p[i]}' yourfile > image.pgm

也就是说,在脚本的开头(即BEGIN{}),输出标题的P5\n512 512\n255,并将像素数组p[]的所有元素归零。然后,在所有后续行上,将输入文件每行上第一个值($ 1)索引的像素设置为255。然后,在结束时(END{})打印像素数组p[]的所有元素,并将整批发送到名为image.pgm的文件。

如果您喜欢使用此功能,则需要下载适用于Windows的awk - 可能来自here

<强> EDITED

如果你想为每个像素使用原始值而不是简单地对输入文件中的每个像素使用纯白色(255),我们需要做更多的工作。首先,当我们读取每个像素时,我们必须保存其值(它在$2中)以及它的位置。然后,最后,我们将不得不将值缩放到某个范围,因此我任意选择文件中的最小值将导致中灰色(即输出图像中的值= 127)并且最大值在您的文件中将导致全白(即输出图像中的值= 255)。输入文件中的所有其他像素将落在中灰色(127)和白色(255)之间的相应(线性)位置。输入文件中没有的任何像素都是黑色的。

awk 'BEGIN {print "P5\n512 512\n255\n";for(i=0;i<512*512;i++)p[i]=0}

     {p[$1]=$2}

     END {
        # Find min and max readings so we can scale them into range [128,255]
        max=0;min=1000000
        for(i=0;i<512*512;i++){
           if(p[i]!=0){
              if(p[i]>max)max=p[i]
              if(p[i]<min)min=p[i]
           }
        }
        # Calculate range of readings
        range=max-min
        scalefactor=128/range
        # Scale all readings
        for(i=0;i<512*512;i++){
           if(p[i]!=0){
              p[i]=127+int((p[i]-min)*scalefactor)
           }
        }
        # Print the values to the pgm file
        for(i=0;i<512*512;i++)printf "%c",p[i]
     }' yourfile > image.pgm

我用这段代码得到的直方图如下:

    14: (127,127,127) #7F7F7F gray(127)
     1: (128,128,128) #808080 gray(128)
     1: (218,218,218) #DADADA gray(218)
     1: (240,240,240) #F0F0F0 gray(240)
     1: (243,243,243) #F3F3F3 gray(243)
     1: (255,255,255) #FFFFFF gray(255)

因此它产生14个像素的中灰色(127),1个像素的128,一个像素218,218个中的一个,240个中的一个,243个中的一个和255个中的一个(白色)。