图片颜色空间转换与切割

一、将彩色图片转换为灰度图片

  • 引入包以及文件路径
#文件路径
#导入相关包
import cv2
import numpy as np
source_path="F:\\jupyter\\source\\picture\\Lena\\lena.jpg"

  • 使用opencv,直接读取为灰度图片
#使用opencv
#直接读取灰度图片
cv_read=cv2.imread(source_path,0)
cv2.imshow('lena',cv_read)
cv2.waitKey(0)

在这里插入图片描述

  • 使用opencv,读取彩色,再转为灰度
#读取彩色图片,后面转换为灰度
cv_read=cv2.imread(source_path)
cv_gray=cv2.cvtColor(cv_read,cv2.COLOR_BGR2GRAY)#灰度化
cv2.imshow('lena',cv_gray)
cv2.waitKey(0)

在这里插入图片描述

  • 不使用opencv的转换函数
#不使用opencv
row,col,channel=cv_read.shape
lena_gray=np.zeros((row,col))
for r in range(row):
    for l in range(col):
        lena_gray[r,l]=1/3*cv_read[r,l,0]+1/3*cv_read[r,l,1]+1/3*cv_read[r,l,2]
cv2.imshow("lena",lena_gray.astype("uint8"))
cv2.waitKey(0)

在这里插入图片描述

二、将彩色图片(RGB)转换为HSV、HSI格式

  1. HSV颜色空间

HSV(Hue, Saturation, Value)是根据颜色的直观特性由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。
这个模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)。
色调H
用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,紫色为300°;
饱和度S
饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。
明度V
明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。
RGB和CMY颜色模型都是面向硬件的,而HSV(Hue Saturation Value)颜色模型是面向用户的。
HSV模型的三维表示从RGB立方体演化而来。设想从RGB沿立方体对角线的白色顶点向黑色顶点观察,就可以看到立方体的六边形外形。六边形边界表示色彩,水平轴表示纯度,明度沿垂直轴测量。

  • 转换代码
#使用opencv
#直接读取图片
cv_read=cv2.imread(source_path)
#转化为hsv格式
lena_hsv=cv2.cvtColor(cv_read,cv2.COLOR_BGR2HSV)
cv2.imshow('lena',lena_hsv)
cv2.waitKey(0)

在这里插入图片描述

  1. HSI颜色空间

HSI〔Hue-Saturation-Intensity(Lightness),HSI或HSL〕颜色模型用H、S、I三参数描述颜色特性,其中H定义颜色的频率,称为色调;S表示颜色的深浅程度,称为饱和度;I表示强度或亮度。
当人观察一个彩色物体时,用色调、饱和度、亮度来描述物体的颜色。色调是描述纯色的属性(纯黄色、橘黄或者红色);饱和度给出一种纯色被白光稀释的程度的度量;亮度是一个主观的描述,实际上,它是不可以测量的,体现了无色的强度概念,并且是描述彩色感觉的关键参数。而强度(灰度)是单色图像最有用的描述子,这个量是可以测量且很容易解释。则将提出的这个模型称作为HSI(色调、饱和度、强度)彩色模型,该模型可在彩色图像中从携带的彩色信息(色调和饱和度)里消去强度分量的影响,使得HSI模型成为开发基于彩色描述的图像处理方法的良好工具,而这种彩色描述对人来说是自然而直观的。
HSI模型是美国色彩学家孟塞尔(H.A.Munseu)于1915年提出的,它反映了人的视觉系统感知彩色的方式,以色调、饱和度和强度三种基本特征量来感知颜色。

  • opencv没有直接将RBG转化为HSI的函数,定义函数转换
def RBG_to_HSI(rgb_img):
    """
    : param rgb_img: RGB彩色图像
    : return       : HSI图像
    """
    #保存原始图像的行列数
    row=np.shape(rgb_img)[0]
    col=np.shape(rgb_img)[1]
    #对原始图像进行复制
    hsi_img=rgb_img.copy()
    #对图像进行通道拆分
    B,G,R=cv2.split(rgb_img)
    #把通道归一化到[0,1]
    [B,G,R]=[i/255.0 for i in ([B,G,R])]
    H=np.zeros((row,col))#定义H通道
    I=(R+G+B)/3.0        #计算I通道
    S=np.zeros((row,col))#定义S通道
    for i in range(row):
        den = np.sqrt((R[i]-G[i])**2+(R[i]-B[i])*(G[i]-B[i]))
        thetha=np.arccos(0.5*(R[i]-B[i]+R[i]-G[i])/den)#计算夹角
        h=np.zeros(col)  #定义临时数组
        #den>0且G>=B的元素h赋值为thetha
        h[B[i]<=G[i]]=thetha[B[i]<=G[i]]
        #den>0且G<=B的元素h赋值为thetha
        h[G[i]<=B[i]]=2*np.pi-thetha[G[i]<=B[i]]
        #den<0的元素h赋值为0
        h[den==0]=0
        H[i]=h/(2*np.pi) #弧度化之后赋值给H通道
    for i in range(row):
        min_=[]
        #找出每组RGB的最小值
        for j in range(col):
            arr=[B[i][j],G[i][j],R[i][j]]
            min_.append(np.min(arr))
        min_=np.array(min_)
        #计算S通道
        S[i]=1-min_*3/(R[i]+B[i]+G[i])
        #I为0的值直接赋值0
        S[i][R[i]+B[i]+G[i]==0]=0
    #扩充到255以方便显示,一般H分量在[0,2pi]之间,S和I在[0,1]之间
    hsi_img[:,:,0]=H*255
    hsi_img[:,:,1]=S*255
    hsi_img[:,:,2]=I*255
    return hsi_img

  • 调用函数
#使用opencv
#读取图片
cv_read=cv2.imread(source_path)
lena_hsi=RBG_to_HSI(cv_read)
cv2.imshow('lena',lena_hsi)
cv2.waitKey(0)

在这里插入图片描述

三、切割车牌

步骤:
1、转化为二值化图片
2、利用开闭运算等操作使一个字成为一个整体
3、利用函数定为或者手工定位

  • 导入函数包
#导入相关包
import cv2
import numpy as np
import os
  • 定义读取和保存路径
pic_folder='F:\\jupyter\\source\\picture\\carband\\'
pic_one="cp1.BMP"
save_path='F:/jupyter/source/picture/carband/carband_cutting/'

  • 创建文件夹的函数
#创建文件夹
def mkdir(path):
    folder=os.path.exists(path)
    if not folder:#判断是否存在
        os.makedirs(path)
  • 图片路径构建及创建文件夹
#图片路径构建及创建文件夹
plate_numbers=pic_folder+pic_one
s_path=save_path+pic_one
mkdir(s_path)

  • 读取文件
plate=cv2.imdecode(np.fromfile(plate_numbers,dtype=np.uint8),-1)
cv2.imshow("carband",plate)
cv2.waitKey(0)

在这里插入图片描述

  • 对图片进行灰度化和二值化处理
#对图片进行处理,进行二值化
plate_gauss=cv2.GaussianBlur(plate,(5,5),0)#高斯降噪
plate_gray=cv2.cvtColor(plate_gauss,cv2.COLOR_BGR2GRAY)#灰度化
thre,plate_bw=cv2.threshold(plate_gray,170,255,cv2.THRESH_BINARY)#二值化
cv2.imshow("cell",plate_bw)
cv2.waitKey(0)

在这里插入图片描述

  • 闭运算,使字这些连在一起,变成一个整体
#闭运算,填充空洞
#构造一个全1的5*5的矩阵
kernel=np.ones((8,8),int)#设置形态学操作卷积的大小
plate_close=cv2.morphologyEx(plate_bw,cv2.MORPH_CLOSE,kernel)
cv2.imshow("cell",plate_close)
cv2.waitKey(0)

在这里插入图片描述

  • 腐蚀运算,去掉中间那个螺丝带来的影响
#腐蚀运算,消除掉中间那颗螺丝的影响
#构造一个全1的5*5的矩阵
kernel=np.ones((3,3),int)#设置形态学操作卷积的大小
plate_corr=cv2.erode(plate_close,kernel,iterations=1)
cv2.imshow("cell",plate_corr)
cv2.waitKey(0)

在这里插入图片描述

  • 定义一个切割并保存的函数
#切割图片并保存
def cutting(start,end,order,src,path):
    dst=src[:,start-3:end+3]
    file_name=path+str(order)+'.jpg'
    cv2.imencode(".jpg",dst)[1].tofile(file_name)
  • 利用findContours进行切割
plate_count,hir=cv2.findContours(plate_corr,cv2.RETR_EXTERNAL ,cv2.CHAIN_APPROX_NONE)
#检测所有轮廓,所有轮廓建立一个等级树结构。
plate_read=cv2.imdecode(np.fromfile(plate_numbers,dtype=np.uint8),-1)
result=plate_read
for i in range(len(plate_count)):
    cnt=plate_count[i]
    x,y,w,h=cv2.boundingRect(cnt)
    save_path_o=s_path+'/opencv/'
    mkdir(save_path_o)
    cutting(x,x+w,i,plate_read,save_path_o)
  • 不使用opencv,手动切割,切割原理

图片二值化之后就只有零和一,代表的就是黑和白,通过判断连续列是否有字体的颜色,第一个有颜色的就是字的起点所在列,之后就是一直在列中有字的颜色,当某一列没有字的颜色的时候,就是这个字的所占的最后一列之后的一列,从而达到定位效果。

  • 实现代码
#flag是用来判断字符个数的,当flag为7时,就代表已经全部识别完了
#word是用来判断一个字的开始和结束,开始时word会加1,结束时word也会加一,所以为2就检测完了一个字
flag=0
word=0
word_start=0
word_end=0
word_color=False#判断某一列中是否有字体的颜色
save_path_a=s_path+'/artificial/'
plate_read=cv2.imdecode(np.fromfile(plate_numbers,dtype=np.uint8),-1)
for i in range(len(plate_corr[0])):#遍历每一列
    word_color=False
    if 255 in plate_corr[:,i]:
        word_color=True
    if word_color==True and word==0:#如果检测到字体的颜色,word+1
        word+=1
        word_start=i
    elif word_color==False and word==1:#判断字结束
        word+=1
        word_end=i+3
        flag+=1
        mkdir(save_path_a)
        cutting(word_start,word_end,flag,plate_read,save_path_a)
    if word==2:
        word=0
        word_start=0
        word_end=0
    if flag==7:
         break     
  • 结果:
    文件夹内容,两者的顺序不一样,利用opencv的寻找轮廓的函数并不是从左到右按顺序来的,而手动切割则是按照顺序来的
    在这里插入图片描述
    在这里插入图片描述

四、总结

本次实验总的来说还是比较有趣,结合了上次实验的算法,达到了不同的实验效果。

五、参考资料

颜色空间转换及切割车牌(python)
数字图像与机器视觉基础2
python cv2 使用中遇到not enough values to unpack (expected 3, got 2) 异常
HSV (HSV颜色模型)
HSI颜色模型

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值