打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
opencv-python笔记(二)

基础:opencv-python-code

图像混合

图片相加

要叠加两张图片,可以用cv2.add()函数,相加两幅图片的形状(高度/宽度/通道数)必须相同。numpy中可以直接用res = img img1相加,但这两者的结果并不相同:

x = np.uint8([250])y = np.uint8([10])print(cv2.add(x, y))  # 250 10 = 260 => 255print(x   y)  # 250 10 = 260 % 256 = 4

如果是二值化图片(只有0和255两种值),两者结果是一样的(用numpy的方式更简便一些)。

图像混合

图像混合cv2.addWeighted()也是一种图片相加的操作,只不过两幅图片的权重不一样,γ相当于一个修正值:

dst=α×img1 β×img2 γ
img1 = cv2.imread('lena_small.jpg')img2 = cv2.imread('opencv-logo-white.png')res = cv2.addWeighted(img1, 0.6, img2, 0.4, 0)

按位操作

cv2.bitwise_and(), cv2.bitwise_not(), cv2.bitwise_or(), cv2.bitwise_xor()分别执行按位与/或/非/异或运算。掩膜就是用来对图片进行全局或局部的遮挡。

img1 = cv2.imread('lena.jpg')img2 = cv2.imread('opencv-logo-white.png')# 把logo放在左上角,所以我们只关心这一块区域rows, cols = img2.shape[:2]roi = img1[:rows, :cols]# 创建掩膜img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)mask_inv = cv2.bitwise_not(mask)# 保留除logo外的背景img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)dst = cv2.add(img1_bg, img2)  # 进行融合img1[:rows, :cols] = dst  # 融合后放在原图上

平滑图像

均值滤波

img = cv2.imread('lena.jpg')blur = cv2.blur(img, (3, 3))  # 均值模糊

方框滤波

# 前面的均值滤波也可以用方框滤波实现:normalize=Trueblur = cv2.boxFilter(img, -1, (3, 3), normalize=True)

高斯滤波

img = cv2.imread('gaussian_noise.bmp')# 均值滤波vs高斯滤波blur = cv2.blur(img, (5, 5))  # 均值滤波gaussian = cv2.GaussianBlur(img, (5, 5), 1)  # 高斯滤波

中值滤波

img = cv2.imread('salt_noise.bmp', 0)# 均值滤波vs中值滤波blur = cv2.blur(img, (5, 5))  # 均值滤波median = cv2.medianBlur(img, 5)  # 中值滤波

双边滤波

img = cv2.imread('lena.jpg')# 双边滤波vs高斯滤波gau = cv2.GaussianBlur(img, (5, 5), 0)  # 高斯滤波blur = cv2.bilateralFilter(img, 9, 75, 75)  # 双边滤波

腐蚀与膨胀

腐蚀

腐蚀的效果是把图片”变瘦”,其原理是在原图的小区域内取局部最小值。因为是二值化图,只有0和255,所以小区域内有一个是0该像素点就为0:

import cv2import numpy as npimg = cv2.imread('j.bmp', 0)kernel = np.ones((5, 5), np.uint8)erosion = cv2.erode(img, kernel)

OpenCV中用cv2.erode()函数进行腐蚀,只需要指定核的大小就行:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 矩形结构kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))  # 椭圆结构kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))  # 十字形结构

膨胀

膨胀与腐蚀相反,取的是局部最大值,效果是把图片”变胖”:
dialation = cv2.dilate(img, kernel)

开/闭运算

先腐蚀后膨胀叫开运算(因为先腐蚀会分开物体,这样容易记住),其作用是:分离物体,消除小区域。这类形态学操作用cv2.morphologyEx()函数实现:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 定义结构元素img = cv2.imread('j_noise_out.bmp', 0)opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)  # 开运算

闭运算则相反:先膨胀后腐蚀(先膨胀会使白色的部分扩张,以至于消除/“闭合”物体里面的小黑洞,所以叫闭运算)

img = cv2.imread('j_noise_in.bmp', 0)closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)  # 闭运算

形态学梯度

获得物体轮廓

img = cv2.imread('school.bmp', 0)gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

顶帽

原图减去开运算的图
tophat = cv2.morphologyEx(img, cv2.MOPRH_TOPHAT, Kernel)

黑帽

闭运算图减去原图
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

轮廓

cv2.findContours()&&cv2.drawContours

import cv2img = cv2.imread('handwriting.jpg')img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 使用Otsu自动阈值,注意用的是cv2.THRESH_BINARY_INVret, thresh = cv2.threshold(    img_gray, 0, 255, cv2.THRESH_BINARY_INV   cv2.THRESH_OTSU)# 寻找轮廓contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)cnt = contours[1]#数组中有0,1两个cv2.drawContours(img, [cnt], 0, (0, 255, 0), 2)cv2.imshow('contours', img)cv2.waitKey(0)

轮廓特征

计算一些轮廓的参数如面积、周长、最小外接矩形等
函数:cv2.contourArea(), cv2.arcLength(), cv2.approxPolyDP()

import cv2import numpy as np# 载入手写数字图片img = cv2.imread('handwriting.jpg', 0)_, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV   cv2.THRESH_OTSU)image, contours, hierarchy = cv2.findContours(thresh, 3, 2)# 创建出两幅彩色图用于绘制img_color1 = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)img_color2 = np.copy(img_color1)# 以数字3的轮廓为例cnt = contours[0]cv2.drawContours(img_color1, [cnt], 0, (0, 0, 255), 2)# 1.轮廓面积area = cv2.contourArea(cnt)  # 4386.5print(area)# 2.轮廓周长perimeter = cv2.arcLength(cnt, True)  # 585.7716print(perimeter)# 3.图像矩M = cv2.moments(cnt)print(M)print(M['m00'])  # 同前面的面积:4386.5cx, cy = M['m10'] / M['m00'], M['m01'] / M['m00']  # 质心print(cx, cy)# 4.图像外接矩形和最小外接矩形x, y, w, h = cv2.boundingRect(cnt)  # 外接矩形cv2.rectangle(img_color1, (x, y), (x   w, y   h), (0, 255, 0), 2)rect = cv2.minAreaRect(cnt)  # 最小外接矩形box = np.int0(cv2.boxPoints(rect))  # 矩形的四个角点并取整# 也可以用astype(np.int)取整cv2.drawContours(img_color1, [box], 0, (255, 0, 0), 2)cv2.imshow('contours', img_color1)cv2.waitKey(0)# 5.最小外接圆(x, y), radius = cv2.minEnclosingCircle(cnt)(x, y, radius) = np.int0((x, y, radius))# 或使用这句话取整:(x, y, radius) = map(int, (x, y, radius))cv2.circle(img_color2, (x, y), radius, (0, 0, 255), 2)# 6.拟合椭圆ellipse = cv2.fitEllipse(cnt)cv2.ellipse(img_color2, ellipse, (0, 255, 0), 2)cv2.imshow('contours2', img_color2)cv2.waitKey(0)# 7.形状匹配img = cv2.imread('shapes.jpg', 0)_, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY   cv2.THRESH_OTSU)image, contours, hierarchy = cv2.findContours(thresh, 3, 2)img_color = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)cnt_a, cnt_b, cnt_c = contours[0], contours[1], contours[2]print(cv2.matchShapes(cnt_b, cnt_b, 1, 0.0))  # 0.0print(cv2.matchShapes(cnt_b, cnt_c, 1, 0.0))  # 2.17e-05print(cv2.matchShapes(cnt_b, cnt_a, 1, 0.0))  # 0.418

直方图

直方图简单来说就是图像中每个像素值的个数统计,比如说一副灰度图中像素值为0的有多少个,1的有多少个……直方图是一种分析图片的手段:


使用cv2.calcHist(images, channels, mask, histSize, ranges)计算,其中:

参数1:要计算的原图,以方括号的传入,如:[img]
参数2:类似前面提到的dims,灰度图写[0]就行,彩色图B/G/R分别传入[0]/[1]/[2]
参数3:要计算的区域,计算整幅图的话,写None
参数4:前面提到的bins
参数5:前面提到的range

import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread('2.jpg', 0)hist = cv2.calcHist([img], [0], None, [256], [0, 256])  # 性能:0.025288 splt.plot(hist)plt.show()cv2.waitKey(0)

自动均衡

#原图与均衡比较import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread('2.jpg', 0)hist = cv2.calcHist([img], [0], None, [256], [0, 256])  # 性能:0.025288 splt.plot(hist)plt.show()equ = cv2.equalizeHist(img)hist2 = cv2.calcHist([equ], [0], None, [256], [0, 256])  # 性能:0.025288 splt.plot(hist2)plt.show()#v2.imshow('equalization', np.hstack((img, equ)))  # 并排显示cv2.waitKey(0)

模版匹配

cv2.matchTemplate()实现模板匹配。首先我们来读入图片和模板:

import cv2import numpy as npfrom matplotlib import pyplot as plt# 1.模板匹配img = cv2.imread('1.jpg', 0)template = cv2.imread('2.jpg', 0)h, w = template.shape[:2]  # rows->h, cols->w# 6种匹配方法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)    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()

同时匹配多个物体

# 1.读入原图和模板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]# 2.标准相关模板匹配res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)threshold = 0.8 # 3.这边是Python/Numpy的知识,后面解释loc = np.where(res >= threshold)  # 匹配程度大于�的坐标y,xfor pt in zip(*loc[::-1]):  # *号表示可选参数    right_bottom = (pt[0]   w, pt[1]   h)    cv2.rectangle(img_rgb, pt, right_bottom, (0, 0, 255), 2)

霍夫变换

学习使用霍夫变换识别出图像中的直线和圆
cv2.HoughLines()霍夫直线变换
cv2.HoughCircles霍夫圆变换

来源:http://www.icode9.com/content-1-172651.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【Python】使用Opencv对图像进行边缘轮廓检测,获得轮廓面积、周长等信息(Contour Features)
史上最全的OpenCV入门教程!这篇够你学习半个月了!万字长文入门
OpenCV Python教程(1、图像的载入、显示和保存)
OpenCV-Python学习教程.3
python+opencv图像处理(八)
Python
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服