纯Python综合图像处理小工具(1)分通道直方图

时间:2022-11-23 14:55:55

平时工作经常需要做些图像分析,需要给图像分通道,计算各个通道的直方图分布特点,这个事儿photoshop也能做,但是用起来不方便,且需要电脑上安装有PS软件,如果用OpenCV 更是需要在visual studio上做很多配置工作。本文充分利用python的便携性和轻量级特点,力图实现一个脚本,到处处理的目标。

注:本文使用Python2.7.8和PIL1.1.7,注意版本问题。

<使用方法>

          1.将待处理图片命名为1.jpg和本文python脚本文件放入同一文件夹;

纯Python综合图像处理小工具(1)分通道直方图

 

          2.运行python脚本,可以获得分通道图片及相应的直方图。

纯Python综合图像处理小工具(1)分通道直方图

 


<效果介绍>

原图:

纯Python综合图像处理小工具(1)分通道直方图 

 

分通道显示:

 纯Python综合图像处理小工具(1)分通道直方图

 各通道直方图

R通道直方图                                                                                                                                                                                

纯Python综合图像处理小工具(1)分通道直方图 

 

G通道直方图  

 纯Python综合图像处理小工具(1)分通道直方图

                                           

B通道直方图

纯Python综合图像处理小工具(1)分通道直方图 

 

 <源码分析>

本文脚本没有使用OpenCV,全部操作均使用了python自带库函数,实现真正的轻量级。

本文工具默认对jpg格式的图片进行修改,其他格式直接修改脚本中im1 = Image.open("1.jpg")图片后缀即可。 

分通道是直接使用的 r,g,b=im1_sp.split()的, 因只对RGB mode的图像有效,所以im1_sp = im1.convert("RGB")先进行了模式转换。 

一张RGB彩色图像经过通道分离,获得三张单通道灰度图像,即python中定义的“L” mode的图像, 然后对每一个灰度图绘制直方图。

直方图绘制是通过 pix = r.load()函数把图像的像素数据进行存储,然后在256级区间进行累加统计,最后使用draw.line函数绘制的。 

工具简单易用,全部代码提供如下,如有问题,欢迎园友反馈! 

 

<全部源码>

#  -*- coding: cp936 -*-
#
阿瓦图像村出品,转载请注明出处 QQ:576916092
import Image,ImageDraw,ImageFilter,random,sys
im1 = Image.open( " 1.jpg ")
 
# #图像处理##
 
# 转换为RGB图像
im1_sp = im1.convert( " RGB ")              

# 将RGB三个通道分开
r,g,b=im1_sp.split()             
 
# 将RGB分通道图像上色
imd = Image.new( " L ",im1.size,0)
r_color= Image.merge( " RGB ",(r,imd,imd))
g_color= Image.merge( " RGB ",(imd,g,imd))
b_color= Image.merge( " RGB ",(imd,imd,b))
 
# R通道histogram
width, height = r.size
pix = r.load()
a = [0]*256
for w  in xrange(width):
     for h  in xrange(height):
        p = pix[w,h]
        a[p] = a[p] + 1
s = max(a)
print a,len(a),s      # 长度256,a保存的分别是颜色范围0-255出现的次数
r_hist = Image.new( ' RGB ',(512,512),(255,255,255))  
draw = ImageDraw.Draw(r_hist)  
 
for k  in range(256):
    # print k,a[k],a[k]*200/s
    a[k] = a[k]*400/s         # 映射范围0-200
    source = (2*k,511)            # 起点坐标y=255, x=[0,1,2....]
    target = (2*k,511-a[k])     # 终点坐标y=255-a[x],a[x]的最大数值是200,x=[0,1,2....]
    draw.line([source, target], (255,0,0))
 
# G通道histogram
width, height = g.size
pix = g.load()
a = [0]*256
for w  in xrange(width):
     for h  in xrange(height):
        p = pix[w,h]
        a[p] = a[p] + 1
s = max(a)
print a,len(a),s      # 长度256,a保存的分别是颜色范围0-255出现的次数
g_hist = Image.new( ' RGB ',(512,512),(255,255,255))  
draw = ImageDraw.Draw(g_hist)  

for k  in range(256):
     # print k,a[k],a[k]*200/s
    a[k] = a[k]*400/s         # 映射范围0-200
    source = (2*k,511)            # 起点坐标y=255, x=[0,1,2....]
    target = (2*k,511-a[k])     # 终点坐标y=255-a[x],a[x]的最大数值是200,x=[0,1,2....]
    draw.line([source, target], (0,255,0))

# B通道histogram
width, height = b.size
pix = b.load()
a = [0]*256
for w  in xrange(width):
     for h  in xrange(height):
        p = pix[w,h]
        a[p] = a[p] + 1
s = max(a)
print a,len(a),s      # 长度256,a保存的分别是颜色范围0-255出现的次数
b_hist = Image.new( ' RGB ',(512,512),(255,255,255))  
draw = ImageDraw.Draw(b_hist)  

for k  in range(256):
     # print k,a[k],a[k]*200/s
    a[k] = a[k]*400/s         # 映射范围0-200
    source = (2*k,511)            # 起点坐标y=255, x=[0,1,2....]
    target = (2*k,511-a[k])     # 终点坐标y=255-a[x],a[x]的最大数值是200,x=[0,1,2....]
    draw.line([source, target], (0,0,255))

im1_mer= Image.merge( " RGB ",(r,g,b))

# #图像保存##

# 单通道图保存
r.save( " 1r.jpg ")
g.save( " 1g.jpg ")
b.save( " 1b.jpg ")

# 上色图保存
r_color.save( " 1rr.jpg ")
g_color.save( " 1gg.jpg ")
b_color.save( " 1bb.jpg ")

# 直方图保存
r_hist.save( " 1r_hist.jpg ")
g_hist.save( " 1g_hist.jpg ")
b_hist.save( " 1b_hist.jpg ")

# #图像显示##

# 单通道图显示
r.show()
g.show()
b.show()
 
# 上色图显示
r_color.show()
g_color.show()
b_color.show()

# 直方图显示
r_hist.show()
g_hist.show()
b_hist.show()