博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenCV1.图像基本操作
阅读量:4031 次
发布时间:2019-05-24

本文共 7890 字,大约阅读时间需要 26 分钟。

1.图像基本操作

opencv常用函数和常用操作

https://blog.csdn.net/qq_45453266/article/details/106698699

文章目录

1.1图像的读取、显示和保存

cv2.imread(filename,flags) :读取图像

读取图片,默认是三通道(BGR)的彩色图,flags=0读入灰度图

该函数有两个参数,第一个参数是图片的地址,第二个参数是读取图像的方式(默认值为1,以RGB格式读取)

Flags指定了所读取图片的颜色类型

cv2.IMREAD_COLOR:加载彩色图片,这个是默认参数,可以直接写1。
cv2.IMREAD_GRAYSCALE:以灰度模式加载图片,可以直接写0。
cv2.IMREAD_UNCHANGED:包括alpha,可以直接写-1

flags >0 返回3通道彩色图

注意:alpha 通道将被忽略,如果需要alpha 通道,请使用负值
=0 返回灰度图
<0 返回原图(带alpha 通道)

cv2.imshow(winname,img) :显示图片

显示图片,需与cv2.waitkey(0)一起使用,不然只显示一瞬间

以窗口的形式显示图片,两个参数,第一个是窗口上显示的名称,第二个是图像在代码中的表示名称

cv2.imwrite(filename,img,params) :保存图片

N个参数,第一个是要保存的图像的名字,如 ‘Rachel.jpg’ ,

第二个是也是图像在代码中的表示名称,此外还有图像的质量等参数,暂且略过

cv2.destroyALLWindows():销毁全部窗口

cv2.destroyWindow(winname):销毁特定窗口

括号里填指定窗口名称

cv2.waitKey(delay):绑定按键

cv2.waitkey(timeout) :显示图片时间

显示图片时间,单位为ms,0代表一直显示

cv2.VideoCapture(name) 读取视频

1.2、图像的缩放

缩放图片是非常常用的操作,cv2里面的函数是:cv2.resize

函数原型:cv2.resize(src, dst, dsize, fx=0, fy=0, interpolation=INTER_LINEAR )

fx,fy表示缩放比例,interpolation是缩放时填充的类型,有以下几种:

INTER_NEAREST(邻近元素插值法)

INTER_LINEAR(缺省值,双线性插值)

INTER_AREA(使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法)

INTER_CUBIC(立方插值)

示例代码:

图片变成原图的0.5倍的灰度图

import cv2 img = cv2.imread('Rachel.jpg', 0) # 注意,第二个参数是0,灰度图new = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)cv2.imshow('Rachel', new)k = cv2.waitKey(0)if k == ord('s'):    cv2.imwrite('Rachel1.jpg', new)    cv2.destroyAllWindows()

1.3、只保留某一通道

#只保留R通道为例   img[:,:,0]=0  #将B通道全部置为0   img[:,:,1]=0  #将R通道全部置为0

1.4、边界填充

top,bottom,left,right分别表示在原图四周扩充边缘的大小

borderType:扩充边缘的类型,就是外插的类型,OpenCV中给出以下几种方式

  • BORDER_REPLICATE:复制法,也就是复制最边缘像素。
  • BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
  • BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
  • BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
  • BORDER_CONSTANT:常量法,常数值填充。
p_top,p_bottom,p_left,p_right=(50,50,50,50) wrap=cv2.copyMakeBorder(img,p_top,p_bottom,p_left,p_right,cv2.BORDER_WRAP)

1.5、混合图像

img = cv2.imread('1.png') img1 = cv2.imread('2.png') #!!!注意shape得出来的是(height,width),resize传入的是(width,height) h, w = img1.shape[:2] #将img的宽高转为img1的宽高 img = cv2.resize(img, (w, h)) #αX1+βX2+b img2 = cv2.addWeighted(img1, 0.4, img, 0.6, 0)

1.6 图像阈值

ret, dst = cv2.threshold(src, thresh, maxval, type)

  • src: 输入图,只能输入单通道图像,通常来说为灰度图

  • dst: 输出图

  • thresh: 阈值

  • maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值

  • type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV

  • cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0

  • cv2.THRESH_BINARY_INV THRESH_BINARY的反转

  • cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变

  • cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0

  • cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转

ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]for i in range(6):    plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')    plt.title(titles[i])    plt.xticks([]), plt.yticks([])# 将生成画图保存为图片plt.savefig('1.jpg')plt.show()

在这里插入图片描述

1. 7图像平滑

原图

在这里插入图片描述

1.7.1 均值滤波

简单的平均卷积操作

blur = cv2.blur(img, (3, 3))cv2.imshow('blur', blur)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

1.7.2-1 方框滤波—normalize=True

基本和均值一样,可以选择归一化

box = cv2.boxFilter(img,-1,(3,3), normalize=True)  cv2.imshow('box', box)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

1.7.2-2 方框滤波—normalize=False

基本和均值一样,可以选择归一化,容易越界

box = cv2.boxFilter(img,-1,(3,3), normalize=False)  cv2.imshow('box', box)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

1.7.3 高斯滤波

高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的

aussian = cv2.GaussianBlur(img, (5, 5), 1)cv2.imshow('aussian', aussian)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

1.7.4 中值滤波

相当于用中值代替

median = cv2.medianBlur(img, 5)  # 中值滤波cv2.imshow('median', median)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

1.8 形态学

1.8.1 腐蚀

kernel = np.ones((3, 3), np.uint8)# 腐蚀操作    img= cv2.erode(img, kernel, iterations=1)

1.8.2 膨胀

kernel = np.ones((3, 3), np.uint8)img = cv2.dilate(img, kernel, 1)

1.9 梯度处理

1.10 边缘检测

img = cv2.imread('1.png', cv2.IMREAD_GRAYSCALE)img1 = cv2.Canny(img, 80, 150)#阈值越大,过滤掉的细节越多img2 = cv2.Canny(img, 20, 200)

1.11 图像金字塔

1.11.1 高斯金字塔

  • 向上采样(放大图像)
img1 = cv2.pyrUp(img)
  • 向下采样(缩小图像)
img2 = cv2.pyrDown(img)

1.11.2拉普拉斯金字塔

拉普拉斯金字塔(原图-(先缩小后放大))

img3 = cv2.pyrUp(cv2.pyrDown(img))img.resize(img3.shape)img4 = img-img3

1.12.1 轮廓检测

cv2.findContours(img,mode,method)

mode:轮廓检索模式

  • RETR_EXTERNAL :只检索最外面的轮廓;
  • RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;
  • RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
  • RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次;

method:轮廓逼近方法

  • CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
  • CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
img = cv2.imread('1.png')# 转化为灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 使用二值图ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 根据灰度二值图找出轮廓contours, hierarchy = cv2.findContours(    thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)# 画出轮廓# 这里要将原图copy一下,不然直接就在原图上画了img1 = img.copy()img2 = cv2.drawContours(img1, contours, -1, (0, 0, 255), 2)

1.12.2 轮廓近似

img = cv2.imread('1.png')# 转化为灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 使用二值图ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 根据灰度二值图找出轮廓contours, hierarchy = cv2.findContours(    thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)cnt = contours[0]# 普朗克算法epsilon = 0.1*lengthapprox = cv2.approxPolyDP(cnt, epsilon, True)img3 = img.copy()img4 = cv2.drawContours(img3, [approx], -1, (0, 0, 255), 2)

1.13 模板匹配

模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv里有6种,然后将每次计算的结果放入一个矩阵里,作为结果输出。假如原图形是AxB大小,而模板是axb大小,则输出结果的矩阵是(A-a+1)x(B-b+1)

  • TM_SQDIFF:计算平方不同,计算出来的值越小,越相关
  • TM_CCORR:计算相关性,计算出来的值越大,越相关
  • TM_CCOEFF:计算相关系数,计算出来的值越大,越相关
  • TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关
  • TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关
  • TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关

公式:

# 以灰度图方式读入img = cv2.imread('2.jpg',0)template = cv2.imread('1_template.png',0)h, w = template.shape[:2]# 可选的算法数组methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',           'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']for meth in methods:    img2 = img.copy()    # 匹配方法的真值    method = eval(meth)    print (method)    res = cv2.matchTemplate(img, template, method)    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)    # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED,取最小值    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:        top_left = min_loc    else:        top_left = max_loc    bottom_right = (top_left[0] + w, top_left[1] + h)    # 画矩形    cv2.rectangle(img2, top_left, bottom_right, 255, 2)    plt.subplot(121), plt.imshow(res, cmap='gray')    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴    plt.subplot(122), plt.imshow(img2, cmap='gray')    plt.xticks([]), plt.yticks([])    plt.suptitle(meth)    plt.show()

匹配多个对象

img_rgb = cv2.imread('mario.jpg')img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)template = cv2.imread('mario_coin.jpg', 0)h, w = template.shape[:2]res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)threshold = 0.8# 取匹配程度大于%80的坐标loc = np.where(res >= threshold)for pt in zip(*loc[::-1]):  # *号表示可选参数    bottom_right = (pt[0] + w, pt[1] + h)    cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)cv2.imshow('img_rgb', img_rgb)cv2.waitKey(0)

1.14 直方图

cv2.calcHist(images,channels,mask,histSize,ranges)

  • images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]
  • channels: 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的参数可以是 [0][1][2] 它们分别对应着 BGR。
  • mask: 掩模图像。统整幅图像的直方图就把它为 None。但是如 果你想统图像某一分的直方图的你就制作一个掩模图像并 使用它。
  • histSize:BIN 的数目。也应用中括号括来
  • ranges: 像素值范围常为 [0256]
img = cv2.imread('cat.jpg',0) #0表示灰度图hist = cv2.calcHist([img],[0],None,[256],[0,256])hist.shapeplt.hist(img.ravel(),256); plt.show()
你可能感兴趣的文章
redis学习总结-- 内部数据 字符串 链表 字典 跳跃表
查看>>
iOS 对象序列化与反序列化
查看>>
iOS 序列化与反序列化(runtime) 01
查看>>
iOS AFN 3.0版本前后区别 01
查看>>
iOS ASI和AFN有什么区别
查看>>
iOS QQ侧滑菜单(高仿)
查看>>
iOS 扫一扫功能开发
查看>>
iOS app之间的跳转以及传参数
查看>>
iOS __block和__weak的区别
查看>>
Android(三)数据存储之XML解析技术
查看>>
Spring JTA应用之JOTM配置
查看>>
spring JdbcTemplate 的若干问题
查看>>
Servlet和JSP的线程安全问题
查看>>
GBK编码下jQuery Ajax中文乱码终极暴力解决方案
查看>>
jQuery性能优化指南
查看>>
Oracle 物化视图
查看>>
PHP那点小事--三元运算符
查看>>
解决国内NPM安装依赖速度慢问题
查看>>
Brackets安装及常用插件安装
查看>>
Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
查看>>