1,出现于myutils.py中的函数
def resize(image, width=None, height=None, inter=cv2.INTER_AREA)
interplolation为缩放时候的差值方式,主要有以下几种:
cv2.INTER_AREA #利用像素关系重采样。当图像缩小时,可以避免波 纹;当图像放大的时候,类似于cv2.INTER_NN。
cv2.INTER_CUBIC # 立方插值
cv2.INTER_LINEAR # 双线形插值
cv2.INTER_NN # 最近邻插值
2,argparse包,argparse 是python自带的命令行参数解析包,可以用来方便地读取命令行参数,当你的代码需要频繁地修改参数的时候,使用这个工具可以将参数和代码分离开来,让你的代码更简洁,适用范围更广。
parser = argparse.ArgumentParser(description = 'This is a test')
parser.add_argument("-p","--port",help='increase output port')
#定义了可选参数-p和--port,赋值后,其值保存在args.port中(其值 都是保存在最后一个定义的参数中)
3,灰度是指黑白图像中的颜色深度,范围一般0-255,白色为255,黑色为0,故黑白图片也称为灰度图像。
若是彩色图像的灰度其实是在转化为黑白图像后的像素值。
如果一个二值灰度图像,它的像素值只能为0或1,我们说它的灰度级为2。
4,np.absolute(a): 计算数组a的绝对值。
5,retval,dst = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)
因为cv2.threshold()会返回两个值,一个是返回值retval,一个是图像目标dst。
所以用的时候常常:
dst = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
只取第二个返回值
6,
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c) # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped) # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]
7,排序函数sorted()
sorted(iterable, cmp=None, key=None, reverse=False)
iterable -- 可迭代对象。
cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
8,
items() 字典函数以列表返回可遍历的(键, 值) 元组数组。
dict = {'Hunan': 'Changsha', 'Hubei': 'Wuhan', 'Sichuan': 'Chengdu'}
print(dict.items())
#输出的字典值 : [('Hunan', 'Changsha'), ('Hubei', 'Wuhan'), ('Sichuan', 'Chengdu')]
for (key,values) in dict.items():
print key,values
以上实例输出结果为:
Hunan Changsha
Hubei Wuhan
Sichuan Chengdu
9,
cv2.putText(img, str(i), (123,456)), font, 2, (0,255,0), 3)
这个函数是opencv里面向图像上添加文本内容的函数.
各参数依次是:图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细
10,
extend() 函数用于在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
参数
seq -- 元素列表
输入:
aList = [123, 'xyz', 'zara', 'abc', 123];
bList = [2009, 'manni'];
aList.extend(bList)
print "Extended List : ", aList ;
输出结果如下:
Extended List : [123, 'xyz', 'zara', 'abc', 123, 2009, 'manni']
11,
imutils包
是在opencv基础上对一些方法进行了再次加工,使这些方法更加简单易用,包括 translation, rotation, resizing, skeletonization, and displaying Matplotlib images 等。
12,图像梯度对意义:
当用均值滤波器降低图像噪声的时候,会带来图像模糊的副作用。我们当然希望看到的是清晰图像。那么,清晰图像和模糊图像之间的差别在哪里呢?从逻辑上考虑,图像模糊是因为图像中物体的轮廓不明显,轮廓边缘灰度变化不强烈,层次感不强造成的,那么反过来考虑,轮廓边缘灰度变化明显些,层次感强些是不是图像就更清晰些呢。
那么,这种灰度变化明显不明显怎样去定义呢。我们学过微积分,知道微分就是求函数的变化率,即导数(梯度),那么对于图像来说,可以用微分来表示图像灰度的变化率。
那么,这个梯度(或者说灰度值的变化率)如何增强图像的清晰度呢?
如果我们把梯度值与对应的像素相加,那么灰度值没有变化的,像素值不变,而有梯度值的,灰度值变大了。
def This_is_a_white: def
####################################
####################################
13,
join()用法
join()方法——用于将序列中的元素以指定的字符连接生成一个新的字符串。
join()方法语法:str.join(sequence),sequence为要连接的元素序列。
str = "-"
seq = ("a", "b", "c") # 字符串序列
# c = [1, 2, 3] 数字不行,变成# c = ["1", "2", "3"]
print(str.join(seq)) # 输出结果为a-b-c
# print("-".join(seq)) 直接这样写也行
# print(“”.join(seq)) 输出结果为abc
"""
myutils.py
"""
import cv2
def sort_contours(cnts, method='left_to_right'):
boundingBoxes = [cv2.boundingRect(c) for c in cnts]
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda x:x[1][0], reverse=False))
return cnts, boundingBoxes
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
if width is None and height is None:
return image
if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation=inter)
return resized
"""
template_match.py
"""
# 主函数
from imutils import contours
import numpy as np
import cv2
import myutils
# 绘画函数
def cv_show(name, img):
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 导入模版
temp = cv2.imread('images/ocr_a_reference.png')
cv_show('temp', temp)
# 预处理
temp_gray = cv2.cvtColor(temp, cv2.COLOR_BGR2GRAY)
cv_show('temp_gray', temp_gray)
temp_binaryzation = cv2.threshold(temp_gray, 10, 255, cv2.THRESH_BINARY_INV)[1]
cv_show('temp_binaryzation', temp_binaryzation)
# 找到模版的轮廓
a_, tempConts, c_ = cv2.findContours(temp_binaryzation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 绘制模版轮廓
cv2.drawContours(temp, tempConts, -1, (0, 0, 255), 2)
cv_show('tempConts', temp)
# 给模版轮廓排序
tempConts = contours.sort_contours(tempConts, method='left-to-right')[0]
digits = {}
# 遍历模版轮廓
for (i, c) in enumerate(tempConts):
(x, y, w, h) = cv2.boundingRect(c)
roi = temp_binaryzation[y:y + h, x:x + w]
roi = cv2.resize(roi, (57, 88))
# 把0-9这十个模版存入字典digits
digits[i] = roi
# 读入信用卡图片
img = cv2.imread('images/credit_card_03.png')
cv_show('img', img)
img = myutils.resize(img, width=300)
# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv_show('gray', gray)
# 二值化
binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show('binary', binary)
# 导入卷积核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 顶帽操作突出明亮部分
tophat = cv2.morphologyEx(binary, cv2.MORPH_TOPHAT, rectKernel)
cv_show('tophat', tophat)
# Sobel求图像梯度,使得轮廓更加清晰
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1) # ksize=-1默认为(3,3)的核
gradX = np.absolute(gradX)
(minval, maxval) = (np.min(gradX), np.max(gradX))
gradX = (255 * (gradX - minval) / (maxval - minval)) # 归一化
gradX = gradX.astype('uint8')
cv_show('gradX', gradX)
# 闭操作,先膨胀后腐蚀,连接区域
close1 = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
cv_show('close1', close1)
# 再次闭操作,填充洞
close2 = cv2.morphologyEx(close1, cv2.MORPH_CLOSE, sqKernel)
cv_show('close2', close2)
# 计算图像的轮廓
(_, imgConts, _) = cv2.findContours(close2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
img_copy = img.copy()
cv2.drawContours(img_copy, imgConts, -1, (0, 0, 255), 2)
cv_show('imgConts', img_copy)
locs = []
# 遍历轮廓,根据长宽比找到合适位置的轮廓并保存到locs
for (i, c) in enumerate(imgConts):
(x, y, w, h) = cv2.boundingRect(c)
ar = w / float(h)
# 选择合适的区域
if ar > 2.5 and ar < 4.0:
if (w > 40 and w < 55) and (h > 10 and h < 20):
locs.append((x, y, w, h))
# 把找到的合适轮廓按照x取值,从左到右从大到小排序
locs = sorted(locs, key=lambda x: x[0])
output = []
# 遍历找到的四组
for (i, (gX, gY, gW, gH)) in enumerate(locs):
groupOut = []
# 根据坐标求每一组
group = gray[gY:gY + gH, gX:gX + gW]
group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show('group', group)
# 计算一组中的轮廓
(_, cnts, _) = cv2.findContours(group, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 给这四个小数字轮廓排序
cnts = contours.sort_contours(cnts, method='left-to-right')[0]
# 计算每组中的数字
for (i, c) in enumerate(cnts):
(x, y, w, h) = cv2.boundingRect(c)
roi = group[y:y + h, x:x + w]
roi = cv2.resize(roi, (57, 88))
#cv_show('digit', roi)
# 计算得分
scores = []
# 模版匹配
for (digit, digitROI) in digits.items():
res = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)
(_, score, _, _) = cv2.minMaxLoc(res)
scores.append(score)
groupOut.append(str(np.argmax(scores))) # 这里要记得转换为str,不然join()会出错
# 画出来
cv2.rectangle(img, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5),
(0, 0, 255), 1)
cv2.putText(img, ''.join(groupOut), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 255, 0), 2)
output.extend(groupOut)
print('This result is {}'.format(''.join(output)))
cv_show('result', img)
**通过这次的项目实战,让我更加熟练了opencv的一些基本操作,从中复习了很多python的基础知识,做完的第二个项目,加油~**
https://www.cnblogs.com/shmily2018/p/11592448.html.
https://www.jianshu.com/p/bb34ddf2a947.
https://blog.csdn.net/weixin_41874898/article/details/99624454.
link.
link.
link.
link.
link.