我有一张黑白图像(或 pdf)文件,想要获取图像水平剖面的直方图。也就是说,对于图像中的每一列,我想要列中像素的灰度值之和。如果图像是 X x Y 像素,我将以 0(对于全黑列)和 255*Y(对于全白列)之间的 X 数字结束。
请看this comic的第二屏|
我想要这样的直方图,但每个 bin 都代表图像中该 x 坐标(像素)处的所有“黑色墨水”。
作为一名贫穷的研究生,我只能使用 Linux 命令行、FOSS 程序(ImageMagick、gnuplot、Perl、g++ 等)。像 GIMP 这样的东西只有在我可以通过终端运行命令时才有用,因为我无法访问 GUI。可视化输出文件对以后有帮助,但不是必需的。
有谁知道我可以提取这些信息的方法吗?搜索“图像配置文件”只会找到有关颜色配置文件的信息。
最佳答案
我将分两步给出答案,使用我最喜欢的两个免费实用程序:python 和 gnuplot。
作为一名(计算)研究生,我的建议是,如果您想免费做事,Python 是您可以学习使用的最通用的工具之一。
这是执行第一部分的 python 脚本,计算灰度值(从白色的 0 到黑色的 255):
#!/usr/bin/python
import Image # basic image processing/manipulation, just what we want
im = Image.open('img.png') # open the image file as a python image object
with open('data.dat', 'w') as f: # open the data file to be written
for i in range(im.size[0]): # loop over columns
counter = sum(im.getpixel((i,j)) for j in range(im.size[1]))
f.write(str(i)+'\t'+str(counter)+'\n') # write to data file
令人震惊的是无痛!现在让 gnuplot 制作直方图*:
#!/usr/bin/gnuplot
set terminal pngcairo size 925,900
set output 'plot.png'
#set terminal pdfcairo
#set output 'plot.pdf'
set multiplot
## first plot
set origin 0,0.025 # this plot will be on the bottom
set size 1,0.75 # and fill 3/4 of the whole canvas
set title "Black count in XKCD 'Self-Description'"
set xlabel 'Column'
set ylabel "Black\ncount" norotate offset screen 0.0125
set lmargin at screen 0.15 # make plot area correct size
set rmargin at screen 0.95 # width = 740 px = (0.95-0.15)*925 px
set border 0 # these settings are just to make the data
set grid # stand out and not overlap with the tics, etc.
set tics nomirror
set xtics scale 0.5 out
set ytics scale 0
set xr [0:740] # x range such that there is one spike/pixel
## uncomment if gnuplot version >= 4.6.0
## this will autoset the x and y ranges
#stats 'data.dat'
#set xr [STATS_min_x:STATS_max_x+1]
#set yr [STATS_min_y:STATS_may_y]
plot 'data.dat' with impulse notitle lc 'black'
## second plot
set origin 0,0.75 # this plot will be on top
set size 1,0.25 # and fill 1/4 of the canvas
unset ylabel; unset xlabel # clean up a bit...
unset border; unset grid; unset tics; unset title
set size ratio -1 # ensures image proper ratio
plot 'img.png' binary filetype=png with rgbimage
unset multiplot # important to unset multiplot!
要运行这些脚本,请将它们保存在与您要绘制的图像相同的目录中(在本例中为 XKCD 漫画,我将其保存为 img.png
)。使它们可执行。在 bash 中这是
$ chmod 755 grayscalecount.py plot.plt
然后(如果python+image模块+gnuplot都安装好了),就可以运行了
$ ./grayscalecount.py
$ ./plot.plt
在我的电脑上,运行 Ubuntu 11.10 和 gnuplot 4.4.3,最后我得到了这个很酷的图:
**旁注*:gnuplot 可以制作很多不同的直方图。我认为这种样式很好地展示了数据,但您可以考虑为 gnuplot histograms 格式化数据.
有很多方法可以让 python 自己制作绘图或使用 gnuplot(matplotlib、pygnuplot、gnuplot-py),但我对这些并不那么熟练。 Gnuplot 非常适合用于绘图的脚本化,并且有很多方法可以使其与 python、bash、C++ 等很好地配合使用。
关于python - 图像 "Black Ink Level"的横轴直方图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13148835/