yanty123 / bp- Goto Github PK
View Code? Open in Web Editor NEW手写识别的一些图像处理
手写识别的一些图像处理
from math import *
import warnings
import struct
import math
import os
#from sklearn.preprocessing import OneHotEncoder
#from matplotlib import pyplot as plt
from collections import Counter
import numpy as np
import cv2
warnings.filterwarnings('ignore')
def edge_padding(img):
'''
作用:边缘填充
'''
h, w = img.shape
pad_length = max(h, w) // 2
padded_img = cv2.copyMakeBorder(img, *([pad_length] * 4), cv2.BORDER_CONSTANT, value = [0, 0, 0])
return padded_img
def get_minAreaRect(img,isminst=False):
'''
作用:获取轮廓最小外界矩形
参数:
image:原图片
ismnist:是否为mnist数据集图片
返回值:
最小外界矩形
'''
threshold_value = 0.3 if isminst else 100
cv2.threshold(img, threshold_value, 1, cv2.THRESH_BINARY_INV, img)
img = np.array(img,np.uint8)
b, contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
rect = cv2.minAreaRect(contours[0])
box = cv2.boxPoints(rect)
box = np.int0(box)
minImg = rotate(img, *box)
return minImg
#由四角坐标截取图片
def rotate(img, pt1, pt2, pt3, pt4):
'''
作用:图片裁剪
参数:
image:原图片
pt1~pt4:四点坐标
返回值:
裁剪后图片
'''
widthRect = math.sqrt((pt4[0] - pt1[0]) ** 2 + (pt4[1] - pt1[1]) ** 2) # 矩形框的宽度
heightRect = math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) **2)
angle = acos((pt4[0] - pt1[0]) / widthRect) * (180 / math.pi) # 矩形框旋转角度
if pt4[1] <= pt1[1]:
angle = -angle
height, width = img.shape[:2]
rotateMat = cv2.getRotationMatrix2D((int(width / 2), int(height / 2)), angle, 1) # 按angle角度旋转图像
heightNew = int(width * math.fabs(sin(math.radians(angle))) + height * math.fabs(cos(math.radians(angle))))
widthNew = int(height * math.fabs(sin(math.radians(angle))) + width * math.fabs(cos(math.radians(angle))))
rotateMat[0, 2] += (widthNew - width) / 2
rotateMat[1, 2] += (heightNew - height) / 2
imgRotation = cv2.warpAffine(img, rotateMat, (widthNew, heightNew), borderValue=(0, 0, 0))
# 旋转后图像的四点坐标
[[pt1[0]], [pt1[1]]] = np.dot(rotateMat, np.array([[pt1[0]], [pt1[1]], [1]]))
[[pt2[0]], [pt2[1]]] = np.dot(rotateMat, np.array([[pt2[0]], [pt2[1]], [1]]))
[[pt3[0]], [pt3[1]]] = np.dot(rotateMat, np.array([[pt3[0]], [pt3[1]], [1]]))
[[pt4[0]], [pt4[1]]] = np.dot(rotateMat, np.array([[pt4[0]], [pt4[1]], [1]]))
# 处理反转的情况
if pt2[1] > pt4[1]:
pt2[1], pt4[1] = pt4[1], pt2[1]
if pt1[0] > pt3[0]:
pt1[0], pt3[0] = pt3[0], pt1[0]
imgOut = imgRotation[int(pt2[1]):int(pt4[1]), int(pt1[0]):int(pt3[0])]
return imgOut
def rotate_bound(image, angle):
'''
作用:图片翻转
参数:
image:原图片
angle:翻转角度
返回值:
翻转后图片
'''
(h, w) = image.shape[:2]
(cX, cY) = (w // 2, h // 2)
M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])
# compute the new bounding dimensions of the image
nW = int((h * sin) + (w * cos))
nH = int((h * cos) + (w * sin))
# adjust the rotation matrix to take into account translation
M[0, 2] += (nW / 2) - cX
M[1, 2] += (nH / 2) - cY
# perform the actual rotation and return the image
img = cv2.warpAffine(image, M, (nW, nH))
return img
def delate(img, size=(4, 4)):
'''
作用:图像膨胀
参数:
image:原图像
size :卷积核大小
'''
'''
cv2.MORPH_RECT: 矩形结构
cv2.MORPH_ELLIPSE: 椭圆结构
cv2.MORPH_CROSS: 十字形结构
'''
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, size)
return cv2.dilate(img, kernel)
def standardizing(img):
'''
作用:图像标准化
1.边缘补白
2.缩小为28 * 28像素
'''
h, w = img.shape
dh, dw = max(h, w) - h, max(h, w) - w
padding = max(h, w) * 3 // 10
img = cv2.copyMakeBorder(img, dh // 2 + padding, dh // 2 + padding, dw // 2 + padding//2, dw // 2 + padding//2,
cv2.BORDER_CONSTANT, value = [0, 0, 0])
'''
NTER_NEAREST 最近邻插值
INTER_LINEAR 双线性插值(默认设置)
INTER_AREA 使用像素区域关系进行重采样。 它可能是图像抽取的首选方法,因为它会产生无云纹理的结果。 但是当图像缩放时,它类似于INTER_NEAREST方法。
INTER_CUBIC 4x4像素邻域的双三次插值
INTER_LANCZOS4 8x8像素邻域的Lanczos插值
'''
img = cv2.resize(img, (28, 28), interpolation=cv2.INTER_LINEAR)
return img
def predict(model, x):
if np.ndim(x) == 1:
return np.argmax(model.forwardprop(x))
else:
p = [model.forwardprop(xi)[0]for xi in x]
print('p:', p)
colidx = np.argmax(p, axis=1)
print('coldix', colidx)
ans = [p[i][colidx[i]] for i in range(len(colidx))]
print('ans', ans)
rowidx = np.argmax(ans)
print('rowdix', rowidx)
print('The number is', colidx[rowidx])
def processing_predict(model, path):
'''
参数:
model:模型
path:图像路径
'''
pre_img = cv2.imread(path, 0)
# padded_img = edge_padding(pre_img)
# min_img = get_minAreaRect(padded_img) #获得最小矩形(摆正数字
min_img = get_minAreaRect(pre_img)
delated_img = delate(min_img) #膨胀
standard_img = standardizing(delated_img) #边缘补白,居中,缩小为28 * 28像素
# print(standardimg)
imglist = [rotate_bound(standard_img, 90 * i).reshape(1, -1) for i in range(4)] #获得旋转后的共四张图像
ans = predict(model, np.array(imglist)) #预测
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.