python之图像仿射变换实战-提取手写数字图片样本

• 一种是 寻找轮廓边缘的部分, 找到最外面的那个外接矩形 , 为了区分, 我们称之为正外接矩形 boundingRect, 如下图绿色矩形部分.
• 另外一种策略是 矩形可以旋转, 找到面积最小的矩形, 刚刚好可以把轮廓套在里面,我们称之为 `*最小外接矩形 * minAreaRect` , 如下图蓝色矩形部分.

正外接矩形 boudningRect

```rect = cv2.boundingRect(cnt)
(x, y, w, h) = rect

```for cidx,cnt in enumerate(contours):
(x, y, w, h) = cv2.boundingRect(cnt)
print('RECT: x={}, y={}, w={}, h={}'.format(x, y, w, h))

```RECT: x=92, y=378, w=94, h=64
RECT: x=381, y=328, w=69, h=102
RECT: x=234, y=265, w=86, h=70
RECT: x=53, y=260, w=61, h=95
RECT: x=420, y=184, w=49, h=66
RECT: x=65, y=124, w=48, h=83
RECT: x=281, y=71, w=70, h=108

```import numpy as np
import cv2
# 读入黑背景下的彩色手写数字
# 转换为gray灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 寻找轮廓
contours, hier = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 声明画布 拷贝自img
canvas = np.copy(img)
for cidx,cnt in enumerate(contours):
(x, y, w, h) = cv2.boundingRect(cnt)
print('RECT: x={}, y={}, w={}, h={}'.format(x, y, w, h))
# 原图绘制圆形
cv2.rectangle(canvas, pt1=(x, y), pt2=(x+w, y+h),color=(255, 255, 255), thickness=3)
# 截取ROI图像
cv2.imwrite("number_boudingrect_cidx_{}.png".format(cidx), img[y:y+h, x:x+w])
cv2.imwrite("number_boundingrect_canvas.png", canvas)

```# 截取ROI图像
cv2.imwrite("number_boudingrect_cidx_{}.png".format(cidx), img[y:y+h, x:x+w])

最小外接矩形 minAreaRect

`minAreaRect` 函数用于 获取最小面积的矩形

```minAreaRect = cv2.minAreaRect(cnt)

```((133.10528564453125, 404.7727966308594), (100.10702514648438, 57.51853942871094), -49.184913635253906)

```((cx, cy), (width, height), theta)

```cx
cy
width
height
theta
```

注意: 上述值均为小数, 不可以直接用于图片索引,或者矩形绘制.

```((cx, cy), (width, height), theta) = cv2.minAreaRect(cnt)
1

```for cidx,cnt in enumerate(contours):
((cx, cy), (width, height), theta) = cv2.minAreaRect(cnt)
print('center: cx=%.3f, cy=%.3f, width=%.3f, height=%.3f, roate_angle=%.3f'%(cx, cy, width, height, theta))

```center: cx=133.105, cy=404.773, width=100.107, height=57.519, roate_angle=-49.185
center: cx=415.190, cy=378.853, width=66.508, height=100.537, roate_angle=-1.710
center: cx=278.323, cy=296.089, width=71.608, height=78.065, roate_angle=-78.440
center: cx=83.000, cy=307.000, width=60.000, height=94.000, roate_angle=0.000
center: cx=448.346, cy=213.731, width=47.068, height=64.718, roate_angle=-11.310
center: cx=89.642, cy=164.695, width=17.204, height=88.566, roate_angle=-25.427
center: cx=330.578, cy=123.387, width=92.325, height=72.089, roate_angle=-66.666

```import numpy as np
import cv2
# 读入黑背景下的彩色手写数字
# 转换为gray灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 寻找轮廓
contours, hier = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 声明画布 拷贝自img
canvas = np.copy(img)
for cidx,cnt in enumerate(contours):
minAreaRect = cv2.minAreaRect(cnt)
# 转换为整数点集坐标
rectCnt = np.int64(cv2.boxPoints(minAreaRect))
# 绘制多边形
cv2.polylines(img=canvas, pts=[rectCnt], isClosed=True, color=(0,0,255), thickness=3)
cv2.imwrite("number_minarearect_canvas.png", canvas)

提取最小外接矩形区域

```# 声明旋转矩阵
rotateMatrix = cv2.getRotationMatrix2D((cx, cy), theta, 1.0)
# 获取旋转后的图像
rotatedImg = cv2.warpAffine(img, rotateMatrix, (img.shape[1], img.shape[0]))

```'''

'''
import numpy as np
import cv2
# 读入黑背景下的彩色手写数字
# 转换为gray灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 寻找轮廓
contours, hier = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cidx,cnt in enumerate(contours):
minAreaRect = cv2.minAreaRect(cnt)
# 转换为整数点集坐标
# rectCnt = np.int64(cv2.boxPoints(minAreaRect))
((cx, cy), (w, h), theta) = minAreaRect
cx = int(cx)
cy = int(cy)
w = int(w)
h = int(h)
# 获取旋转矩阵
rotateMatrix = cv2.getRotationMatrix2D((cx, cy), theta, 1.0)
rotatedImg = cv2.warpAffine(img, rotateMatrix, (img.shape[1], img.shape[0]))
pt1 = (int(cx - w/2), int(cy - h/2))
pt2 = (int(cx + w/2), int(cy + h/2))
# 原图绘制矩形区域
cv2.rectangle(rotatedImg, pt1=pt1, pt2=pt2,color=(255, 255, 255), thickness=3)
# 绘制中心点
cv2.circle(rotatedImg, (cx, cy), 5, color=(255, 0, 0), thickness=-1)
cv2.imwrite("minarearect_cidx_{}.png".format(cidx), rotatedImg)

数字样本图像转换为统一尺寸

```import numpy as np
import cv2
from glob import glob
img_paths = glob('./数字图像处理/*.png')
# 新的维度为10×20
new_dimension = (15, 25)
for img_path in img_paths:
# 读入灰度图
img_name = img_path.split('/')[-1]
# 缩放
resized = cv2.resize(img, new_dimension)
# 二值化图片
ret,thresh = cv2.threshold(resized,10,255,0)
cv2.imwrite('./number/'+img_name,thresh)

资源传送门

1. 关注【 做一个柔情的程序猿 】公众号
2. 在【 做一个柔情的程序猿 】公众号后台回复 【 python资料 】【 2020秋招 】 即可获取相应的惊喜哦！

「:heart: 感谢大家」

1. 点赞支持下吧，让更多的人也能看到这篇内容（ 收藏不点赞，都是耍流氓 -_-
2. 欢迎在留言区与我分享你的想法，也欢迎你在留言区记录你的思考过程。