图像“黑色墨水量”的水平轴直方图

Posted

技术标签:

【中文标题】图像“黑色墨水量”的水平轴直方图【英文标题】:Histogram of an Image's "Black Ink Level" by Horizontal Axis 【发布时间】:2012-10-20 08:57:46 【问题描述】:

我有一个黑白图像(或 pdf)文件,并且想要获取图像水平轮廓的直方图。也就是说,对于图像中的每一列,我想要列中像素的灰度值之和。如果图像是 X x Y 像素,我将得到介于 0(全黑列)和 255*Y(全白列)之间的 X 个数字。

请看this comic的第二个面板

我想要这样的直方图,但每个 bin 将代表图像中该 x 坐标(像素)处的所有“黑色墨水”。

作为一名贫穷的研究生,我受限于只使用 Linux 命令行、FOSS 程序(ImageMagick、gnuplot、Perl、g++ 等)。只有当我可以通过终端运行命令时,像 GIMP 这样的东西才会有帮助,因为我无法访问 GUI。视觉输出文件对以后会有帮助,但不是必需的。

有谁知道我可以提取这些信息的方法吗?搜索“图像配置文件”只会导致有关颜色配置文件的信息。

【问题讨论】:

你有 python(和 Image 模块)可用吗? 如果它是免费的,我可以得到它。几年前我尝试过学习 Python,但没有一个语法在没有工作的情况下卡住了;这可能是我的第一个项目(输入 python 会将我带到 >>> 提示符)。 好的,很酷。您使用的是什么操作系统? 【参考方案1】:

我将分两幕给出答案,使用我最喜欢的两个免费实用程序: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 module+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++ 等很好地配合使用。

【讨论】:

先生,您是 *** 社区的楷模。我使用了您之前的评论/提示和Paul's good work 和plot "dataFile" using 1 并得到了类似的东西。感谢您的提示和清晰、逐步、综合的教程。我希望这个问题足够笼统,可以引导未来的 Google 员工找到您的答案。 不客气,欢迎来到***!想出这个答案让我很开心。 非常好的答案(+1)。我格式化了您的 python 代码以使其符合 PEP-8 并使用上下文管理器来确保文件被正确刷新(您的旧方法不能保证当您退出程序时所有数据实际上都在文件中,因为你没有关闭文件)。我建议使用sum 来删除内部循环:sum(im.getpixel((i,j)) for j in range(im.size[1]))。如果im 支持类似索引的numpy,sum(im[i,:]) 也可以工作(但我不知道那个,因为我通常不使用Image)。 谢谢,@mgilson!你教会了我一些关于 python 语法的新东西,它们确实使脚本更加紧凑​​和优雅。我更新了我的答案。我不认为图像对象支持 numpy 样式的索引,否则我也会把它放进去。 @andyras -- 通过 *** 上的 python 标签,我学到了很多很酷的 Python 技巧 -- 它比 gnuplot 获得更多的流量 :)。当您在上面提到pygnuplot 时,我也很高兴——尽管最近我开始玩matplotlib 一点点。它也很漂亮(不是我打算很快放弃 pygnuplot!)

以上是关于图像“黑色墨水量”的水平轴直方图的主要内容,如果未能解决你的问题,请参考以下文章

九图像直方图

R语言使用car包的scatterplotMatrix函数绘制散点图矩阵并添加线性和loess拟合线在主对角线上放置箱图密度或直方图在图像边缘添加轴须图rug可以基于分组变量绘制散点图矩阵

【R语言】--- 直方图

OpenCV 例程200篇93. 噪声模型的直方图

OpenCV 完整例程93. 噪声模型的直方图

OpenCV 完整例程93. 噪声模型的直方图