平时工作经常需要做些图像分析,需要给图像分通道,计算各个通道的直方图分布特点,这个事儿photoshop也能做,但是用起来不方便,且需要电脑上安装有PS软件,如果用OpenCV, 更是需要在visual studio上做很多配置工作。本文充分利用python的便携性和轻量级特点,力图实现一个脚本,到处处理的目标。
1.将待处理图片命名为1.jpg和本文python脚本文件放入同一文件夹;
2.运行python脚本,可以获得分通道图片及相应的直方图。
原图:
分通道显示:
各通道直方图
R通道直方图
G通道直方图
B通道直方图
本文脚本没有使用OpenCV,全部操作均使用了python自带库函数,实现真正的轻量级。
本文工具默认对jpg格式的图片进行修改,其他格式直接修改脚本中im1 = Image.open("1.jpg")图片后缀即可。
分通道是直接使用的 r,g,b=im1_sp.split()的, 因只对RGB mode的图像有效,所以im1_sp = im1.convert("RGB")先进行了模式转换。
直方图绘制是通过 pix = r.load()函数把图像的像素数据进行存储,然后在256级区间进行累加统计,最后使用draw.line函数绘制的。
工具简单易用,全部代码提供如下,如有问题,欢迎园友反馈!
1 # -*- coding: cp936 -*-
2 import Image,ImageDraw
3 import ImageFilter,random,sys
4 im1 = Image.open("1.jpg")
5
6 ##图像处理##
7
8 #转换为RGB图像
9 im1_sp = im1.convert("RGB")
10
11 #将RGB三个通道分开
12 r,g,b=im1_sp.split()
13
14 #将RGB分通道图像上色
15 imd = Image.new("L",im1.size,0)
16 r_color= Image.merge("RGB",(r,imd,imd))
17 g_color= Image.merge("RGB",(imd,g,imd))
18 b_color= Image.merge("RGB",(imd,imd,b))
19
20 #R通道histogram
21 width, height = r.size
22 pix = r.load()
23 a = [0]*256
24 for w in xrange(width):
25 for h in xrange(height):
26 p = pix[w,h]
27 a[p] = a[p] + 1
28 s = max(a)
29 print a,len(a),s #长度256,a保存的分别是颜色范围0-255出现的次数
30 r_hist = Image.new(‘RGB‘,(512,512),(255,255,255))
31 draw = ImageDraw.Draw(r_hist)
32
33 for k in range(256):
34 #print k,a[k],a[k]*200/s
35 a[k] = a[k]*400/s #映射范围0-200
36 source = (2*k,511) #起点坐标y=255, x=[0,1,2....]
37 target = (2*k,511-a[k]) #终点坐标y=255-a[x],a[x]的最大数值是200,x=[0,1,2....]
38 draw.line([source, target], (255,0,0))
39
40 #G通道histogram
41 width, height = g.size
42 pix = g.load()
43 a = [0]*256
44 for w in xrange(width):
45 for h in xrange(height):
46 p = pix[w,h]
47 a[p] = a[p] + 1
48 s = max(a)
49 print a,len(a),s #长度256,a保存的分别是颜色范围0-255出现的次数
50 g_hist = Image.new(‘RGB‘,(512,512),(255,255,255))
51 draw = ImageDraw.Draw(g_hist)
52
53 for k in range(256):
54 #print k,a[k],a[k]*200/s
55 a[k] = a[k]*400/s #映射范围0-200
56 source = (2*k,511) #起点坐标y=255, x=[0,1,2....]
57 target = (2*k,511-a[k]) #终点坐标y=255-a[x],a[x]的最大数值是200,x=[0,1,2....]
58 draw.line([source, target], (0,255,0))
59
60 #B通道histogram
61 width, height = b.size
62 pix = b.load()
63 a = [0]*256
64 for w in xrange(width):
65 for h in xrange(height):
66 p = pix[w,h]
67 a[p] = a[p] + 1
68 s = max(a)
69 print a,len(a),s #长度256,a保存的分别是颜色范围0-255出现的次数
70 b_hist = Image.new(‘RGB‘,(512,512),(255,255,255))
71 draw = ImageDraw.Draw(b_hist)
72
73 for k in range(256):
74 #print k,a[k],a[k]*200/s
75 a[k] = a[k]*400/s #映射范围0-200
76 source = (2*k,511) #起点坐标y=255, x=[0,1,2....]
77 target = (2*k,511-a[k]) #终点坐标y=255-a[x],a[x]的最大数值是200,x=[0,1,2....]
78 draw.line([source, target], (0,0,255))
79
80 im1_mer= Image.merge("RGB",(r,g,b))
81
82 ##图像保存##
83
84 #单通道图保存
85 r.save("1r.jpg")
86 g.save("1g.jpg")
87 b.save("1b.jpg")
88
89 #上色图保存
90 r_color.save("1rr.jpg")
91 g_color.save("1gg.jpg")
92 b_color.save("1bb.jpg")
93
94 #直方图保存
95 r_hist.save("1r_hist.jpg")
96 g_hist.save("1g_hist.jpg")
97 b_hist.save("1b_hist.jpg")
98
99 ##图像显示##
100
101 #单通道图显示
102 r.show()
103 g.show()
104 b.show()
105
106 #上色图显示
107 r_color.show()
108 g_color.show()
109 b_color.show()
110
111 #直方图显示
112 r_hist.show()
113 g_hist.show()
114 b_hist.show()