• 玩转Python图片处理 (OpenCV-Python )


        OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

       OpenCV-Python是OpenCV的Python的API接口,它拥有OpenCV C++ API的功能,同时也拥有Python语言的特性,可以做到跨平台使用。但值得注意的是在Python3(目前使用的是Python3.7)里对OpenCV-Python接口的中文支持并不是很友好。

    安装:

    sudo pip3 install opencv-python

    直方图模块安装:

    pip3 install matplotlib

    简单的读取一张图片:

     1 import cv2 #导入opencv库
     2 
     3 #读取一张图片,地址不能带中文
     4 imgviewx=cv2.imread("imgx/zcy.jpg")
     5 
     6 #创建一个窗口,中文显示会出乱码
     7 cv2.namedWindow("东小东标题")
     8 
     9 #显示图片,参数:(窗口标识字符串,imread读入的图像)
    10 cv2.imshow("东小东标题",imgviewx)
    11 
    12 #窗口等待任意键盘按键输入,0为一直等待,其他数字为毫秒数
    13 cv2.waitKey(0)
    14 
    15 #销毁窗口,退出程序
    16 cv2.destroyAllWindows()

    其它属性详细介绍:

      1 import cv2 #导入opencv库
      2 import numpy as np
      3 
      4 #.........................................................................
      5 #读取一张图片,地址不能带中文
      6 '''
      7 第二个参数,取值可为:
      8 cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道 
      9 cv2.IMREAD_GRAYSCALE:读入灰度图片 
     10 cv2.IMREAD_UNCHANGED:读入完整图片,包括alpha通道(png有,jpg无)
     11 '''
     12 #imgviewx=cv2.imread("imgx/wa.jpg")
     13 imgviewx=cv2.imread("imgx/DONG.jpg",cv2.IMREAD_COLOR)
     14 
     15 #.........................................................................
     16 #获取图片信息
     17 #一个像素有三个通道,BGR
     18 print(imgviewx.shape)#输出:(1080, 1920, 3) 高像素,宽像素,通道数
     19 print(imgviewx.size)# 120000  总通道数=高* 宽* 通道数
     20 print(imgviewx.dtype)# uint8  3个通道每个通道占的位数(8位,一个字节)
     21 #print(imgviewx) #输出效果视乎与下条相同
     22 #print(np.array(imgviewx)) #输出每个像素点的参数( B , G , R )
     23 #获取图片 B G R 各均值, #(204.46305102040816, 208.50832244897958, 217.29540408163263, 0.0) ,红色部分最多
     24 print(cv2.mean(imgviewx))
     25 #获取方差,也会打印均值,可用均值方差都为零判断图片无效
     26 #print(cv2.meanStdDev(imgviewx))
     27 
     28 
     29 
     30 #.........................................................................
     31 #图片处理
     32 #备份图片
     33 imgviewx1=imgviewx.copy()
     34 
     35 #均值模糊,主要用于去除图片噪点
     36 #读取图片并实现图片的模糊效果,参数:(读取图片,(X轴方向模糊,Y轴方向模糊))
     37 #imgviewx=cv2.blur(imgviewx,(5,5))
     38 
     39 #中值模糊,主要用于去除椒盐(烧烤配料)噪点
     40 #参数:(图片信息,模糊值)
     41 #imgviewx=cv2.medianBlur(imgviewx,9)
     42 
     43 #普通高斯模糊
     44 #参数:(图片信息,参数1,参数2)参数1和参数2只能设置一个
     45 #imgviewx=cv2.GaussianBlur(imgviewx,(0,0),1)
     46 
     47 #保留边缘(像素差),高斯模糊
     48 #参数(图片信息,0,要用怎样的方式(越大则越细),空间复杂度(越大越复杂))
     49 imgviewx=cv2.bilateralFilter(imgviewx,0,50,6)
     50 
     51 
     52 #美颜,美白效果valuex值越大越白
     53 #valuex=50;
     54 #imgviewx=cv2.bilateralFilter(cv2.imread("imgx/zcy.jpg"),valuex,valuex * 2,valuex / 2)
     55 
     56 #对比度和亮度调整
     57 #duix=0.5 #对比度
     58 #lightx=0  #亮度
     59 #imgviewx=cv2.addWeighted(imgviewx,duix,np.zeros(imgviewx.shape,imgviewx.dtype),1-duix,lightx)
     60 
     61 
     62 
     63 #显示文字
     64 # 参数:图像,文字内容, 坐标( x , y ) ,字体,大小,颜色( B , G ,R ),字体厚度
     65 #颜色值为0-255
     66 font = cv2.FONT_HERSHEY_SIMPLEX  # 定义字体
     67 imgviewx = cv2.putText(imgviewx,"DONG XIAO DONG",(10, 50), font, 1.2, (0, 0, 255), 5)
     68 
     69 
     70 #像素取反
     71 #imgviewx=cv2.bitwise_not(imgviewx)
     72 
     73 
     74 
     75 #遍历图片,效率低,不推荐使用
     76 def xgtp():
     77    global imgviewx
     78    gx,kx,tx=imgviewx.shape#得到像素高度,像素宽度,通道数
     79 
     80    for g in range(0,gx):
     81        for k in range(0,kx):  #这里得到的是每个像素点,每个点由RGB三色构成
     82            if(k>0 and k<100):
     83                imgviewx[g,k,0]=0       # B
     84                imgviewx[g,k,1]=255       #  G
     85                imgviewx[g,k,2]=255        #  R
     86            else:
     87                imgviewx[g, k, 0] = imgviewx[g, k, 0] #获取到原来的值
     88                imgviewx[g, k, 1] = imgviewx[g, k, 1]
     89                imgviewx[g, k, 2] = imgviewx[g, k, 2]
     90 
     91 #创建一个图形,使用np,所以效率高
     92 def cjtx():
     93     # 初始化像素点值全为0 (rgb都为零,所以是黑色)
     94     #参数:([高,宽,通道数],每个通道占的位数(一个字节))
     95     imgx=np.zeros([400,600,3],np.uint8)
     96 
     97     #初始化像素点值为全为1
     98     #imgx[110:130,50:70,2]表示一个范围:[高度起始点:高度结束点,宽度起始点:宽度结束点,哪个通道],起始点均以左上角
     99     #imgx[:,:,0]=np.ones([400,600],np.uint8)*255  #最终结果为第一个通道(B)全为255,所以是蓝色
    100     imgx[110:130,50:70,1]=np.ones([20,20],np.uint8)*255
    101     cv2.imshow("第二个图形窗口",imgx)
    102 
    103 #图片区域处理
    104 def pictureArea():
    105     global imgviewx
    106     #得到截图
    107     areax=imgviewx[110:529,778:1200]
    108     #将图片由RGB(3通道)转换为灰度(2通道)
    109     areax=cv2.cvtColor(areax,cv2.COLOR_BGR2GRAY)
    110     #将图片有2通道还原成3通道,但色彩不能还原
    111     areax2=cv2.cvtColor(areax,cv2.COLOR_GRAY2RGB)
    112     #处理后的区域写到原图上
    113     imgviewx[110:529, 778:1200]=areax2
    114     #显示截图
    115     cv2.imshow("area",areax)
    116 
    117 #泛洪填充,相似像素填充
    118 def fill_color():
    119     global imgviewx
    120     h,w,t=imgviewx.shape
    121     #必要参数
    122     maskx=np.zeros([h+2,w+2],np.uint8)
    123     #参数接收:(图片信息,必要参数,参考点位置坐标,填充的颜色,查找范围:最低像素(参考减所写),查找范围:最高像素(参考加所写),全部填充)
    124     cv2.floodFill(imgviewx,maskx,(100,100),(0,255,0),(100,100,100),(50,50,50),cv2.FLOODFILL_FIXED_RANGE)
    125 
    126 
    127 
    128 #通道分离与合并
    129 def tongdao():
    130     global imgviewx
    131     b,g,r=cv2.split(imgviewx)#通道分离
    132     cv2.imshow("bb",b)#通道图单独显示
    133     cv2.imshow("gg",g)
    134     cv2.imshow("rr",r)
    135 
    136     imgviewx[:,:,1]=135 #改变单个通道(0,1,2 => B,G,R)
    137     cv2.imshow("chang red ",imgviewx)
    138 
    139     imgviewx=cv2.merge([b,g,r])#合并通道
    140 
    141 #像素运算
    142 def pixel_operation():
    143     #读入两张大小和通道相同的图片
    144     img1=cv2.imread("imgx/img1.jpg")
    145     img2=cv2.imread("imgx/img2.jpg")
    146     print(img1.shape, "=====", img2.shape)
    147     # 创建一个大小可调整的窗口
    148     cv2.namedWindow("operation", cv2.WINDOW_NORMAL)
    149     cv2.imshow("img111", img1)
    150     cv2.imshow("img222",img2)
    151     #处理图片
    152     #像素点相加,如0(黑色),255(白色),0+255=255(白色),超过255还是白色
    153     #imgoperation=cv2.add(img1,img2)
    154     #像素相减,如0(黑色),255(白色),0-255=-255=0(黑色)
    155     #imgoperation=cv2.subtract(img1,img2)
    156     #像素相乘,255(白色),0/255=0(黑色)
    157     #imgoperation=cv2.divide(img1,img2)
    158     #像素相乘,255(白色),0*255=0(黑色)
    159     #imgoperation=cv2.multiply(img2,img1)
    160     #像素与,二进制与,如0与255为00000000&11111111=00000000
    161     imgoperation=cv2.bitwise_and(img1,img2)
    162     #像素或
    163     imgoperation=cv2.bitwise_or(img1,img2)
    164 
    165     #显示处理后的图片
    166     cv2.imshow("operation", imgoperation)
    167 
    168 
    169 
    170 #.......................................................................
    171 #视频处理,视频无声音
    172 def vediox():
    173     ved=cv2.VideoCapture("imgx/vv.mp4")#打开视频
    174     while True:
    175         ret,tux=ved.read()
    176         if ret== False:#判断视频是否播放完毕
    177             break
    178         else:
    179             cv2.imshow("wideo1111",tux)#每帧显示
    180             hsv=cv2.cvtColor(tux,cv2.COLOR_BGR2HSV)#转换成HSV图片格式,对颜色敏感
    181             lowx=np.array([37,43,46])#表格在后面给出
    182             uppx=np.array([77,255,255])
    183             # 播放此输出的目标是白色
    184             tux2=cv2.inRange(hsv,lowx,uppx)#利用低指和高指匹配延时,所匹配的是绿色
    185             #播放此输出的目标是原色
    186             tux3 = cv2.bitwise_and(tux,tux, mask=tux2)
    187 
    188             cv2.imshow("video222",tux3)
    189 
    190             if 27==cv2.waitKey(20):#按键退出播放
    191                 break
    192 
    193 
    194 #.........................................................................
    195 #创建一个窗口,中文显示会出乱码,第一个参数为窗口唯一标识字符串
    196 #窗口大小可调整,默认参数为c v2.WINDOW_AUTOSIZE 根据图像大小自动创建大小
    197 #可建多个
    198 cv2.namedWindow("东小东标题",cv2.WINDOW_NORMAL)
    199 
    200 
    201 #.........................................................................
    202 #创建鼠标点击事件回调函数,(事件,x轴位置,y轴位置,标记,属性)
    203 def drawxxx(event,x,y,flags,param):
    204     if event==cv2.EVENT_LBUTTONDOWN:
    205         print("鼠标按下",x,y)
    206     #elif event==cv2.EVENT_MOUSEMOVE:
    207        # print("鼠标滑动")
    208     elif event==cv2.EVENT_LBUTTONUP:
    209         print("鼠标抬起")
    210 
    211 #注册鼠标监听事件(窗口,回调函数)
    212 cv2.setMouseCallback("东小东标题",drawxxx)
    213 
    214 #.........................................................................
    215 t1=cv2.getTickCount()#利用cpu时间......
    216 #xgtp()#调用图片像素遍历函数
    217 #cjtx()#调用创建图形函数
    218 #vediox()#调用视频处理函数
    219 #tongdao()#通道处理
    220 #pixel_operation()#像素点的加减乘除等处理
    221 #pictureArea()#图片区域处理
    222 #fill_color()#泛洪填充,相似像素填充
    223 t2=cv2.getTickCount()
    224 timesx=(t2-t1)/cv2.getTickFrequency()
    225 print("花费时间:%s 毫秒"%(timesx*1000))
    226 
    227 
    228 #显示图片,参数:(窗口唯一标识字符串,imread读入的图像)
    229 #可以不基于窗口,可建多个
    230 cv2.imshow("东小东标题",imgviewx)
    231 
    232 
    233 #.........................................................................
    234 #将图片保存,写入到文件
    235 cv2.imwrite("2.jpg",imgviewx)
    236 
    237 
    238 
    239 #.........................................................................
    240 #窗口退出
    241 #窗口等待任意键盘按键输入,0为一直等待,其他数字为毫秒数
    242 #等待时间到则返回-1,如有键盘按键按下则返回按键的ASCII码
    243 #可使用print(cv2.waitKey(0))获取该按键值
    244 keyx=cv2.waitKey(0)
    245 print(keyx)
    246 if keyx==27:
    247     print("你按下了键盘的:ESC键")
    248 
    249 #.........................................................................
    250 #销毁窗口,退出程序
    251 cv2.destroyAllWindows()

    模拟实现一个简单的拍照程序:

     1 import cv2            #导入opencv库
     2 import numpy as np
     3 
     4 #调用摄像头
     5 def videox():
     6     vix=cv2.VideoCapture(0) #打开摄像头
     7     while True:
     8         ret,tu=vix.read()    # ret为返回值,tu为当前帧
     9         tu1=cv2.flip(tu,1)   #图像反转,1为左右对换,-1为上下对换
    10         cv2.imshow("东小东标题",tu1)  #显示图片在窗口上
    11         if 65==cv2.waitKey(10):        #等待大写 A 键盘按键按下
    12             cv2.imwrite("DONG.jpg",tu1)#保存停止帧图片
    13             break
    14 
    15 cv2.namedWindow("东小东标题")#创建一个窗口,中文显示会出乱码问题
    16 
    17 videox()  #调用摄像头函数
    18 
    19 print(cv2.waitKey(0))#等待任意键按下,并输出该按键的值
    20 
    21 cv2.destroyAllWindows()#销毁窗口

    直方图基本:

     1 import cv2 #导入opencv库
     2 import numpy
     3 #直方图均衡化,对比度改变
     4 def equalization_rgb(imgtu):
     5     #只能使用灰度图片
     6     imgx=cv2.cvtColor(imgtu,cv2.COLOR_RGB2GRAY)#转换为灰度
     7 
     8     #默认参数,自接使用
     9     #imgtu=cv2.equalizeHist(imgx)#均衡化
    10 
    11     #可修改参数clipLimit的值得到不一样效果
    12     chanlx=cv2.createCLAHE(clipLimit=30.0,tileGridSize=(8,8))
    13     imgtu=chanlx.apply(imgx)
    14 
    15     cv2.imshow("equalization",imgtu)#显示
    16 
    17 
    18 #直方图比较,图片相似度比较,遍历像素点,速度慢慢
    19 def create_compara(imgtu):
    20     h,w,t=imgtu.shape
    21     rgbx=numpy.zeros([16*16*16,1],numpy.float32)
    22     bsize=256/16
    23     for row in range(h):
    24         for col in range(w):
    25             b=imgtu[row,col,0]
    26             g=imgtu[row,col,1]
    27             r=imgtu[row,col,2]
    28             index=numpy.int(b/bsize)*16*16+numpy.int(g/bsize)*16+numpy.int(r/bsize)
    29             rgbx[numpy.int(index),0]=rgbx[numpy.int(index),0]+1
    30     return rgbx
    31 
    32 def compare_ing():
    33     img1=cv2.imread("imgx/xxG.png")
    34     img2=cv2.imread("imgx/xxR.png")
    35     hist1=create_compara(img1)
    36     hist2=create_compara(img2)
    37     cv2.imshow("img1111",img1)
    38     cv2.imshow("img2222",img2)
    39     va1=cv2.compareHist(hist1,hist2,cv2.HISTCMP_BHATTACHARYYA)
    40     va2=cv2.compareHist(hist1,hist2,cv2.HISTCMP_CORREL)
    41     va3=cv2.compareHist(hist1,hist2,cv2.HISTCMP_CHISQR)
    42     print("巴氏距离,越小越相似(0,1):",va1)
    43     print("相关性,越接近于1,越相似:",va2)
    44     print("卡方,越小越相似:",va3)
    45 
    46 
    47 #读取一张图片,地址不能带中文
    48 imgviewx=cv2.imread("imgx/zcy.jpg")
    49 
    50 #创建一个窗口,中文显示会出乱码
    51 cv2.namedWindow("东小东标题")
    52 
    53 #显示图片,参数:(窗口标识字符串,imread读入的图像)
    54 cv2.imshow("东小东标题",imgviewx)
    55 
    56 #------------------
    57 #equalization_rgb(imgviewx)#直方图均衡化,提高对比度
    58 compare_ing()#直方图比较,图片相似度
    59 
    60 #-------------------
    61 
    62 #窗口等待任意键盘按键输入,0为一直等待,其他数字为毫秒数
    63 cv2.waitKey(0)
    64 
    65 #销毁窗口,退出程序
    66 cv2.destroyAllWindows()

    模板匹配:

     1 import cv2 #导入opencv库
     2 
     3 #参数:(要寻找的目标,原图片)
     4 def templatex(img_target,img_root):
     5 
     6     #模板匹配方法
     7     #toolx=cv2.TM_SQDIFF_NORMED
     8     toolx=cv2.TM_CCORR_NORMED
     9     #toolx=cv2.TM_CCOEFF_NORMED
    10 
    11     h,w=img_target.shape[:2]#获取目标图像的高和宽
    12     #操作匹配
    13     result=cv2.matchTemplate(img_root,img_target,toolx)
    14     #得到区域
    15     min_x,max_x,min_y,max_y=cv2.minMaxLoc(result)
    16 
    17     #获取起始点坐标
    18     if toolx==cv2.TM_SQDIFF_NORMED:
    19         tl=min_y
    20     else:
    21         tl=max_y
    22     #获取结束点坐标,其中tl[0]表示起始点x轴值,tl[1]表示y
    23     br=(tl[0]+w,tl[1]+h)
    24     #创建一个矩形框,参数(要写到的图片,起始点坐标,结束点坐标,颜色值,厚度)
    25     cv2.rectangle(img_root,tl,br,(0,0,255),5)
    26     #显示图片
    27     cv2.imshow("img_rootxx",img_root)
    28 
    29 
    30 
    31 #读取一张图片,地址不能带中文
    32 imgviewx=cv2.imread("imgx/wa.jpg")
    33 
    34 #创建一个窗口,中文显示会出乱码
    35 cv2.namedWindow("东小东标题",cv2.WINDOW_NORMAL)
    36 
    37 #获取原图片截图
    38 areax = imgviewx[110:529, 778:1200]
    39 cv2.imshow("jjjttt",areax)
    40 
    41 templatex(areax,imgviewx)
    42 
    43 
    44 #显示图片,参数:(窗口标识字符串,imread读入的图像)
    45 cv2.imshow("东小东标题",imgviewx)
    46 
    47 #窗口等待任意键盘按键输入,0为一直等待,其他数字为毫秒数
    48 cv2.waitKey(0)
    49 
    50 #销毁窗口,退出程序
    51 cv2.destroyAllWindows()

    二值化,黑白图片:

     1 import cv2 #导入opencv库
     2 
     3 #读取一张图片,地址不能带中文
     4 imgviewx=cv2.imread("imgx/wa.jpg")
     5 
     6 #创建一个窗口,中文显示会出乱码
     7 cv2.namedWindow("东小东标题")
     8 
     9 imgviewx2=imgviewx.copy()
    10 #得到灰度图片
    11 imgviewx2=cv2.cvtColor(imgviewx2,cv2.COLOR_BGR2GRAY)
    12 #二值化图像,黑白图像,只有0和1,0为0,1为255
    13 ret,imgviewx2=cv2.threshold(imgviewx2,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)
    14 #二值化方法2
    15 imgviewx2=cv2.adaptiveThreshold(imgviewx2,200,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,25,5)
    16 
    17 
    18 #显示图片,参数:(窗口标识字符串,imread读入的图像)
    19 cv2.imshow("img222222",imgviewx2)
    20 cv2.imshow("东小东标题",imgviewx)
    21 
    22 #窗口等待任意键盘按键输入,0为一直等待,其他数字为毫秒数
    23 cv2.waitKey(0)
    24 
    25 #销毁窗口,退出程序
    26 cv2.destroyAllWindows()

     附录:

    HSV取值对应表:

    树莓派(2018-06-27-raspbian-stretch.img)安装需要的依赖包:

    sudo apt-get install libatlas-base-dev

    sudo apt-get install libjasper-runtime

    sudo pip3 install opencv-contrib-python

    sudo apt-get install libhdf5-dev

    sudo apt-get install libhdf5-serial-dev

    sudo apt install libqtgui4

    sudo apt install libqt4-test

    sudo apt-get install libcv-dev


  • 相关阅读:
    javascript简易下拉菜单效果
    精通javascript笔记(智能社)——简易tab选项卡及应用面向对象方法实现
    精通JS正则表达式(转)
    精通javascript笔记(智能社)——数字时钟
    ERROR: transport error 202: bind failed: Address already in use
    理解git对象
    InvocationHandler中invoke()方法的调用问题
    深入理解Java Proxy机制(转)
    IP、子网的详述 ——IP分类、网关地址,子网掩码、子网作用(转)
    getRequestDispatcher()与sendRedirect()的区别
  • 原文地址:https://www.cnblogs.com/dongxiaodong/p/10134904.html
Copyright © 2020-2023  润新知