OpenCV 是一个基于 BSD 许可 (开源) 发行的跨平台计算机视觉库, 可以运行在 Linux,Windows,Android 和 Mac OS 操作系统上. 它轻量级而且高效 -- 由一系列 C 函数和少量 C++ 类构成, 同时提供了 Python,Ruby,MATLAB 等语言的接口, 实现了图像处理和计算机视觉方面的很多通用算法.
OpenCV-Python 是 OpenCV 的 python 的 API 接口, 它拥有 OpenCV C++ API 的功能, 同时也拥有 Python 语言的特性, 可以做到跨平台使用.
安装:
sudo pip3 install opencv-python
直方图模块安装:
pip3 install matplotlib
简单的读取一张图片:
- import cv2 #导入 opencv 库
- #读取一张图片, 地址不能带中文
- imgviewx=cv2.imread("imgx/zcy.jpg")
- #创建一个窗口, 中文显示会出乱码
- cv2.namedWindow("东小东标题")
- #显示图片, 参数:(窗口标识字符串, imread 读入的图像)
- cv2.imshow("东小东标题",imgviewx)
- #窗口等待任意键盘按键输入, 0 为一直等待, 其他数字为毫秒数
- cv2.waitKey(0)
- #销毁窗口, 退出程序
- cv2.destroyAllWindows()
其它属性详细介绍:
- import cv2 #导入 opencv 库
- import numpy as np
- #.........................................................................
- #读取一张图片, 地址不能带中文
- '''
- 第二个参数, 取值可为:
- cv2.IMREAD_COLOR: 默认参数, 读入一副彩色图片, 忽略 alpha 通道
- cv2.IMREAD_GRAYSCALE: 读入灰度图片
- cv2.IMREAD_UNCHANGED: 读入完整图片, 包括 alpha 通道(png 有, jpg 无)
- ''' #imgviewx=cv2.imread("imgx/wa.jpg")
- imgviewx=cv2.imread("imgx/DONG.jpg",cv2.IMREAD_COLOR)
- #.........................................................................
- #获取图片信息
- #一个像素有三个通道, BGR
- print(imgviewx.shape)# 输出:(1080, 1920, 3) 高像素, 宽像素, 通道数
- print(imgviewx.size)# 120000 总通道数 = 高 * 宽 * 通道数
- print(imgviewx.dtype)# uint8 3 个通道每个通道占的位数(8 位, 一个字节)
- #print(imgviewx) #输出效果视乎与下条相同
- #print(np.array(imgviewx)) #输出每个像素点的参数( B , G , R )
- #获取图片 B G R 各均值, #(204.46305102040816, 208.50832244897958, 217.29540408163263, 0.0) , 红色部分最多
- print(cv2.mean(imgviewx))
- #获取方差, 也会打印均值, 可用均值方差都为零判断图片无效
- #print(cv2.meanStdDev(imgviewx))
- #.........................................................................
- #图片处理
- #备份图片
- imgviewx1=imgviewx.copy()
- #均值模糊, 主要用于去除图片噪点
- #读取图片并实现图片的模糊效果, 参数:(读取图片,(X 轴方向模糊, Y 轴方向模糊))
- #imgviewx=cv2.blur(imgviewx,(5,5))
- #中值模糊, 主要用于去除椒盐 (烧烤配料) 噪点
- #参数:(图片信息, 模糊值)
- #imgviewx=cv2.medianBlur(imgviewx,9)
- #普通高斯模糊
- #参数:(图片信息, 参数 1, 参数 2)参数 1 和参数 2 只能设置一个
- #imgviewx=cv2.GaussianBlur(imgviewx,(0,0),1)
- #保留边缘(像素差), 高斯模糊
- #参数(图片信息, 0, 要用怎样的方式(越大则越细), 空间复杂度(越大越复杂))
- imgviewx=cv2.bilateralFilter(imgviewx,0,50,6)
- #美颜, 美白效果 valuex 值越大越白
- #valuex=50;
- #imgviewx=cv2.bilateralFilter(cv2.imread("imgx/zcy.jpg"),valuex,valuex * 2,valuex / 2)
- #对比度和亮度调整
- #duix=0.5 #对比度
- #lightx=0 #亮度
- #imgviewx=cv2.addWeighted(imgviewx,duix,np.zeros(imgviewx.shape,imgviewx.dtype),1-duix,lightx)
- #显示文字
- # 参数: 图像, 文字内容, 坐标( x , y ) , 字体, 大小, 颜色( B , G ,R ), 字体厚度
- #颜色值为 0-255
- font = cv2.FONT_HERSHEY_SIMPLEX # 定义字体
- imgviewx = cv2.putText(imgviewx,"DONG XIAO DONG",(10, 50), font, 1.2, (0, 0, 255), 5)
- #像素取反
- #imgviewx=cv2.bitwise_not(imgviewx)
- #遍历图片, 效率低, 不推荐使用
- def xgtp():
- global imgviewx
- gx,kx,tx=imgviewx.shape# 得到像素高度, 像素宽度, 通道数
- for g in range(0,gx):
- for k in range(0,kx): #这里得到的是每个像素点, 每个点由 RGB 三色构成
- if(k>0 and k<100):
- imgviewx[g,k,0]=0 # B
- imgviewx[g,k,1]=255 # G
- imgviewx[g,k,2]=255 # R
- else:
- imgviewx[g, k, 0] = imgviewx[g, k, 0] #获取到原来的值
- imgviewx[g, k, 1] = imgviewx[g, k, 1]
- imgviewx[g, k, 2] = imgviewx[g, k, 2]
- #创建一个图形, 使用 np, 所以效率高
- def cjtx():
- # 初始化像素点值全为 0 (rgb 都为零, 所以是黑色)
- #参数:([高, 宽, 通道数], 每个通道占的位数(一个字节))
- imgx=np.zeros([400,600,3],np.uint8)
- #初始化像素点值为全为 1
- #imgx[110:130,50:70,2]表示一个范围:[高度起始点: 高度结束点, 宽度起始点: 宽度结束点, 哪个通道], 起始点均以左上角
- #imgx[:,:,0]=np.ones([400,600],np.uint8)*255 #最终结果为第一个通道 (B) 全为 255, 所以是蓝色
- imgx[110:130,50:70,1]=np.ones([20,20],np.uint8)*255
- cv2.imshow("第二个图形窗口",imgx)
- #图片区域处理
- def pictureArea():
- global imgviewx
- #得到截图
- areax=imgviewx[110:529,778:1200]
- #将图片由 RGB(3 通道)转换为灰度(2 通道)
- areax=cv2.cvtColor(areax,cv2.COLOR_BGR2GRAY)
- #将图片有 2 通道还原成 3 通道, 但色彩不能还原
- areax2=cv2.cvtColor(areax,cv2.COLOR_GRAY2RGB)
- #处理后的区域写到原图上
- imgviewx[110:529, 778:1200]=areax2
- #显示截图
- cv2.imshow("area",areax)
- #泛洪填充, 相似像素填充
- def fill_color():
- global imgviewx
- h,w,t=imgviewx.shape
- #必要参数
- maskx=np.zeros([h+2,w+2],np.uint8)
- #参数接收:(图片信息, 必要参数, 参考点位置坐标, 填充的颜色, 查找范围: 最低像素(参考减所写), 查找范围: 最高像素(参考加所写), 全部填充)
- cv2.floodFill(imgviewx,maskx,(100,100),(0,255,0),(100,100,100),(50,50,50),cv2.FLOODFILL_FIXED_RANGE)
- #通道分离与合并
- def tongdao():
- global imgviewx
- b,g,r=cv2.split(imgviewx)# 通道分离
- cv2.imshow("bb",b)# 通道图单独显示
- cv2.imshow("gg",g)
- cv2.imshow("rr",r)
- imgviewx[:,:,1]=135 #改变单个通道(0,1,2 => B,G,R)
- cv2.imshow("chang red",imgviewx)
- imgviewx=cv2.merge([b,g,r])# 合并通道
- #像素运算
- def pixel_operation():
- #读入两张大小和通道相同的图片
- img1=cv2.imread("imgx/img1.jpg")
- img2=cv2.imread("imgx/img2.jpg")
- print(img1.shape, "=====", img2.shape)
- # 创建一个大小可调整的窗口
- cv2.namedWindow("operation", cv2.WINDOW_NORMAL)
- cv2.imshow("img111", img1)
- cv2.imshow("img222",img2)
- #处理图片
- #像素点相加, 如 0(黑色),255(白色),0+255=255(白色), 超过 255 还是白色
- #imgoperation=cv2.add(img1,img2)
- #像素相减, 如 0(黑色),255(白色),0-255=-255=0(黑色)
- #imgoperation=cv2.subtract(img1,img2)
- #像素相乘, 255(白色),0/255=0(黑色)
- #imgoperation=cv2.divide(img1,img2)
- #像素相乘, 255(白色),0*255=0(黑色)
- #imgoperation=cv2.multiply(img2,img1)
- #像素与, 二进制与, 如 0 与 255 为 00000000&11111111=00000000
- imgoperation=cv2.bitwise_and(img1,img2)
- #像素或
- imgoperation=cv2.bitwise_or(img1,img2)
- #显示处理后的图片
- cv2.imshow("operation", imgoperation)
- #.......................................................................
- #视频处理, 视频无声音
- def vediox():
- ved=cv2.VideoCapture("imgx/vv.mp4")# 打开视频
- while True:
- ret,tux=ved.read()
- if ret== False:# 判断视频是否播放完毕
- break
- else:
- cv2.imshow("wideo1111",tux)# 每帧显示
- hsv=cv2.cvtColor(tux,cv2.COLOR_BGR2HSV)# 转换成 HSV 图片格式, 对颜色敏感
- lowx=np.array([37,43,46])# 表格在后面给出
- uppx=np.array([77,255,255])
- # 播放此输出的目标是白色
- tux2=cv2.inRange(hsv,lowx,uppx)# 利用低指和高指匹配延时, 所匹配的是绿色
- #播放此输出的目标是原色
- tux3 = cv2.bitwise_and(tux,tux, mask=tux2)
- cv2.imshow("video222",tux3)
- if 27==cv2.waitKey(20):# 按键退出播放
- break
- #.........................................................................
- #创建一个窗口, 中文显示会出乱码, 第一个参数为窗口唯一标识字符串
- #窗口大小可调整, 默认参数为 c v2.WINDOW_AUTOSIZE 根据图像大小自动创建大小
- #可建多个
- cv2.namedWindow("东小东标题",cv2.WINDOW_NORMAL)
- #.........................................................................
- #创建鼠标点击事件回调函数,(事件, x 轴位置, y 轴位置, 标记, 属性)
- def drawxxx(event,x,y,flags,param):
- if event==cv2.EVENT_LBUTTONDOWN:
- print("鼠标按下",x,y)
- #elif event==cv2.EVENT_MOUSEMOVE:
- # print("鼠标滑动")
- elif event==cv2.EVENT_LBUTTONUP:
- print("鼠标抬起")
- #注册鼠标监听事件(窗口, 回调函数)
- cv2.setMouseCallback("东小东标题",drawxxx)
- #.........................................................................
- t1=cv2.getTickCount()# 利用 CPU 时间......
- #xgtp()# 调用图片像素遍历函数
- #cjtx()# 调用创建图形函数
- #vediox()# 调用视频处理函数
- #tongdao()# 通道处理
- #pixel_operation()# 像素点的加减乘除等处理
- #pictureArea()# 图片区域处理
- #fill_color()# 泛洪填充, 相似像素填充
- t2=cv2.getTickCount()
- timesx=(t2-t1)/cv2.getTickFrequency()
- print("花费时间:%s 毫秒"%(timesx*1000))
- #显示图片, 参数:(窗口唯一标识字符串, imread 读入的图像)
- #可以不基于窗口, 可建多个
- cv2.imshow("东小东标题",imgviewx)
- #.........................................................................
- #将图片保存, 写入到文件
- cv2.imwrite("2.jpg",imgviewx)
- #.........................................................................
- #窗口退出
- #窗口等待任意键盘按键输入, 0 为一直等待, 其他数字为毫秒数
- #等待时间到则返回 - 1, 如有键盘按键按下则返回按键的 ASCII 码
- #可使用 print(cv2.waitKey(0))获取该按键值
- keyx=cv2.waitKey(0)
- print(keyx)
- if keyx==27:
- print("你按下了键盘的: ESC 键")
- #.........................................................................
- #销毁窗口, 退出程序
- cv2.destroyAllWindows()
模拟实现一个简单的拍照程序:
- import cv2 #导入 opencv 库
- import numpy as np
- #调用摄像头
- def videox():
- vix=cv2.VideoCapture(0) #打开摄像头
- while True:
- ret,tu=vix.read() # ret 为返回值, tu 为当前帧
- tu1=cv2.flip(tu,1) #图像反转, 1 为左右对换,-1 为上下对换
- cv2.imshow("东小东标题",tu1) #显示图片在窗口上
- if 65==cv2.waitKey(10): #等待大写 A 键盘按键按下
- cv2.imwrite("DONG.jpg",tu1)# 保存停止帧图片
- break
- cv2.namedWindow("东小东标题")# 创建一个窗口, 中文显示会出乱码问题
- videox() #调用摄像头函数
- print(cv2.waitKey(0))# 等待任意键按下, 并输出该按键的值
- cv2.destroyAllWindows()# 销毁窗口
直方图基本:
- import cv2 #导入 opencv 库
- import numpy
- #直方图均衡化, 对比度改变
- def equalization_rgb(imgtu):
- #只能使用灰度图片
- imgx=cv2.cvtColor(imgtu,cv2.COLOR_RGB2GRAY)# 转换为灰度
- #默认参数, 自接使用
- #imgtu=cv2.equalizeHist(imgx)# 均衡化
- #可修改参数 clipLimit 的值得到不一样效果
- chanlx=cv2.createCLAHE(clipLimit=30.0,tileGridSize=(8,8))
- imgtu=chanlx.apply(imgx)
- cv2.imshow("equalization",imgtu)# 显示
- #直方图比较, 图片相似度比较, 遍历像素点, 速度慢慢
- def create_compara(imgtu):
- h,w,t=imgtu.shape
- rgbx=numpy.zeros([16*16*16,1],numpy.float32)
- bsize=256/16
- for row in range(h):
- for col in range(w):
- b=imgtu[row,col,0]
- g=imgtu[row,col,1]
- r=imgtu[row,col,2]
- index=numpy.int(b/bsize)*16*16+numpy.int(g/bsize)*16+numpy.int(r/bsize)
- rgbx[numpy.int(index),0]=rgbx[numpy.int(index),0]+1
- return rgbx
- def compare_ing():
- img1=cv2.imread("imgx/xxG.png")
- img2=cv2.imread("imgx/xxR.png")
- hist1=create_compara(img1)
- hist2=create_compara(img2)
- cv2.imshow("img1111",img1)
- cv2.imshow("img2222",img2)
- va1=cv2.compareHist(hist1,hist2,cv2.HISTCMP_BHATTACHARYYA)
- va2=cv2.compareHist(hist1,hist2,cv2.HISTCMP_CORREL)
- va3=cv2.compareHist(hist1,hist2,cv2.HISTCMP_CHISQR)
- print("巴氏距离, 越小越相似(0,1):",va1)
- print("相关性, 越接近于 1, 越相似:",va2)
- print("卡方, 越小越相似:",va3)
- #读取一张图片, 地址不能带中文
- imgviewx=cv2.imread("imgx/zcy.jpg")
- #创建一个窗口, 中文显示会出乱码
- cv2.namedWindow("东小东标题")
- #显示图片, 参数:(窗口标识字符串, imread 读入的图像)
- cv2.imshow("东小东标题",imgviewx)
- #------------------
- #equalization_rgb(imgviewx)# 直方图均衡化, 提高对比度
- compare_ing()# 直方图比较, 图片相似度
- #-------------------
- #窗口等待任意键盘按键输入, 0 为一直等待, 其他数字为毫秒数
- cv2.waitKey(0)
- #销毁窗口, 退出程序
- cv2.destroyAllWindows()
模板匹配:
- import cv2 #导入 opencv 库
- #参数:(要寻找的目标, 原图片)
- def templatex(img_target,img_root):
- #模板匹配方法
- #toolx=cv2.TM_SQDIFF_NORMED
- toolx=cv2.TM_CCORR_NORMED
- #toolx=cv2.TM_CCOEFF_NORMED
- h,w=img_target.shape[:2]# 获取目标图像的高和宽
- #操作匹配
- result=cv2.matchTemplate(img_root,img_target,toolx)
- #得到区域
- min_x,max_x,min_y,max_y=cv2.minMaxLoc(result)
- #获取起始点坐标
- if toolx==cv2.TM_SQDIFF_NORMED:
- tl=min_y
- else:
- tl=max_y
- #获取结束点坐标, 其中 tl[0]表示起始点 x 轴值, tl[1]表示 y
- br=(tl[0]+w,tl[1]+h)
- #创建一个矩形框, 参数(要写到的图片, 起始点坐标, 结束点坐标, 颜色值, 厚度)
- cv2.rectangle(img_root,tl,br,(0,0,255),5)
- #显示图片
- cv2.imshow("img_rootxx",img_root)
- #读取一张图片, 地址不能带中文
- imgviewx=cv2.imread("imgx/wa.jpg")
- #创建一个窗口, 中文显示会出乱码
- cv2.namedWindow("东小东标题",cv2.WINDOW_NORMAL)
- #获取原图片截图
- areax = imgviewx[110:529, 778:1200]
- cv2.imshow("jjjttt",areax)
- templatex(areax,imgviewx)
- #显示图片, 参数:(窗口标识字符串, imread 读入的图像)
- cv2.imshow("东小东标题",imgviewx)
- #窗口等待任意键盘按键输入, 0 为一直等待, 其他数字为毫秒数
- cv2.waitKey(0)
- #销毁窗口, 退出程序
- cv2.destroyAllWindows()
二值化, 黑白图片:
- import cv2 #导入 opencv 库
- #读取一张图片, 地址不能带中文
- imgviewx=cv2.imread("imgx/wa.jpg")
- #创建一个窗口, 中文显示会出乱码
- cv2.namedWindow("东小东标题")
- imgviewx2=imgviewx.copy()
- #得到灰度图片
- imgviewx2=cv2.cvtColor(imgviewx2,cv2.COLOR_BGR2GRAY)
- #二值化图像, 黑白图像, 只有 0 和 1,0 为 0,1 为 255
- ret,imgviewx2=cv2.threshold(imgviewx2,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)
- #二值化方法 2
- imgviewx2=cv2.adaptiveThreshold(imgviewx2,200,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,25,5)
- #显示图片, 参数:(窗口标识字符串, imread 读入的图像)
- cv2.imshow("img222222",imgviewx2)
- cv2.imshow("东小东标题",imgviewx)
- #窗口等待任意键盘按键输入, 0 为一直等待, 其他数字为毫秒数
- cv2.waitKey(0)
- #销毁窗口, 退出程序
- cv2.destroyAllWindows()
树莓派 (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
来源: https://www.cnblogs.com/dongxiaodong/p/10134904.html