2012-10-30 4 views
8

흑백 이미지 (또는 pdf) 파일을 가지고 있고 이미지의 가로 프로필 막대 그래프를 얻고 싶습니다. 즉, 이미지의 각 열에 대해 열의 픽셀의 회색 음영 값 합계가 필요합니다. 이미지가 X x Y 픽셀 인 경우 0 (완전히 검은 색 인 열)과 255 * Y (완전히 흰색 인 열) 사이의 X 숫자로 끝납니다. 가로축의 이미지 "검은 색 잉크 수준"막대 그래프

은이 같은 히스토그램을하고자 this comic Comic

의 제 2 패널을보십시오 있지만, 각 빈은 x 좌표 (픽셀)에서 이미지의 모든 '블랙 잉크'를 나타내는 것이다.

저는 대학원생으로서 Linux 명령 행, FOSS 프로그램 (ImageMagick, gnuplot, Perl, g ++ 등) 만 사용하여 제한됩니다. 김프와 같은 것은 터미널에 명령을 실행할 수있는 경우에만 도움이 될 것입니다. GUI에 액세스 할 수 없기 때문입니다. 나중에 시각적 출력 파일이 도움이되지만 필요하지는 않습니다.

누구든지이 정보를 추출 할 수있는 방법을 알고 있습니까? '이미지 프로필'을 검색하면 색상 프로필에 대한 정보로 연결됩니다.

+1

파이썬 (그리고 이미지 모듈)을 사용할 수 있습니까? – andyras

+0

무료라면 얻을 수 있습니다. 나는 파이썬을 몇 년 전에 배우려고했지만 어떤 구문도 작동하지 않고 붙어 있지 않습니다. 이것은 나의 첫 번째 프로젝트 일 수있다. ('python '을 입력하면'>>>'프롬프트로 간다.) – user1717828

+0

좋습니다.어떤 OS를 사용하고 있습니까? – andyras

답변

12

필자는 내가 좋아하는 무료 유틸리티 인 python과 gnuplot 중 두 가지를 사용하여 대답을 줄 것이다.

동료 (전산) 대학원생으로서, 무료로 작업하기를 원한다면 사용법을 배울 수있는 가장 유용한 도구 중 하나입니다.

#!/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 

놀랍게도 통증 :

여기 파이썬 (흑백 255 행 0)에서 그레이 스케일 값을 계산하는 첫 번째 부분을 수행 스크립트이야! 이제 히스토그램 *을 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! 

는 (이 경우 내가 img.png로 저장 XKCD 만화에) 플롯 할 이미지와 같은 디렉토리에 저장, 이러한 스크립트를 실행하려면. 실행 가능하게 만드십시오. (파이썬 + 이미지 모듈 +의 gnuplot이 모두 설치되어있는 경우) bash는 이것은 다음

$ chmod 755 grayscalecount.py plot.plt 

, 당신은, 내가 얻을의 gnuplot 4.4.3와 우분투 11.10를 실행하는 컴퓨터에

$ ./grayscalecount.py 
$ ./plot.plt 

를 실행할 수 있습니다 끝이 멋진 줄거리 :

enter image description here

** 사이드 참고 * : 수의 gnuplot 다른 히스토그램 플롯이 많이 있습니다. 이 스타일이 데이터를 잘 보여줬다 고 생각했지만 데이터 형식을 gnuplot histograms으로 볼 수 있습니다.

파이썬 자체 또는 gnuplot (matplotlib, pygnuplot, gnuplot-py)을 사용하여 파이썬을 만들 수있는 많은 방법이 있지만 필자는 그다지 쉽지 않습니다. Gnuplot은 대단히 스크립트 화가 가능하며, 파이썬, bash, C++ 등으로 멋지게 연출할 수있는 많은 방법이 있습니다.

+1

당신, 선생님, StackOverflow 커뮤니티의 모델입니다. 나는 당신의 코멘트/힌트를 이전의 [Paul 's good work] (http://stackoverflow.com/questions/4188104/pil-create-one-dimensional-histogram-of-image-color-lightness#4199541)와'plot "dataFile"1을 사용하여 비슷한 것을 얻었습니다. 팁과 명쾌하고 단계별로 통합 된 튜토리얼을 보내 주셔서 감사합니다. 미래의 Google 직원을 귀하의 답변으로 이끌 수있을 정도로 일반적인 질문이기를 바랍니다. – user1717828

+0

당신은 환영합니다, 그리고 stackoverflow에 오신 것을 환영합니다! 나는 그 해답을 생각해 내는데 많은 즐거움을 누렸다. – andyras

+1

아주 좋은 대답 (+1). 나는 당신의 파이썬 코드를 PEP-8을 준수하도록 포맷했고 파일을 적절히 플러시 할 수 있도록 컨텍스트 관리자를 사용했다. (이전 방식은 프로그램을 종료 할 때 실제로 파일에있는 모든 데이터를 보장하지 못했기 때문이다. 파일을 닫지 않았습니다.) 나는 내부 루프를 제거하기 위해'sum'의 사용을 권고 할 것이다 :'sum (im.size [1])에서 j에 대한 sum (im.getpixel ((i, j))'. 'im '이 인덱스처럼 numpy를 지원한다면,'sum (im [i, :])'도 작동 할 것이다. (보통'Image'를 사용하지 않기 때문에 나는 그것에 대해 모른다. – mgilson