写在前面
使用python对图像进行透视校正的代码现在有很多了,我这个也是借鉴了某一个博客里面的代码,因为我也是刚入门,还有好多东西都不明白,只能做到哪就学到哪,所以如果出现了错误请批评指正!谢谢朋友们[狗头]!
需求
将原本倾斜的物体通过透视校正
步骤
-
步骤一 选择图片,更改GetPoint.py文件路径,点击图片中比萨斜塔的四个顶点后会自动更改图片的名称,自动标点如图中的红圈表示:
-
步骤二 更改Reset.py代码中的图片路径,运行代码(记得加.jpg)
-
步骤三 得到正的比萨斜塔(会裁剪,但是不会降低图片画质)
大概就是这样
代码
#Reset.py
# -*- coding: utf-8 -*-
"""
Created on Fri Dec 4 08:50:44 2020
@author: 褚凡
"""
import os
import re
import cv2
import numpy as np
oripath = "C:\\Users\\Administrator\\Desktop\\picture\\"
savpath = "C:\\Users\\Administrator\\Desktop\\picture\\"
def Resize(img, pts1, pts2, filename, width, heigh):
# print(pts1, pts2)
# 计算出3×3的矩阵
matrix = cv2.getPerspectiveTransform(pts1, pts2)
# 使用矩阵对图形进行换算,并按大小展示
imgOutput = cv2.warpPerspective(img, matrix, (int(width), int(heigh)))
# cv2.namedWindow("image", cv2.WINDOW_NORMAL)
# cv2.namedWindow("output", cv2.WINDOW_NORMAL)
# cv2.resizeWindow("image", int(width/4), int(heigh/4));
# cv2.resizeWindow("output", int(width/4), int(heigh/4));
# cv2.imshow("image", img)
# cv2.imshow("output", imgOutput)
cv2.imwrite(savpath + filename + '.jpg', imgOutput)
cv2.waitKey(0)
cv2.destroyAllWindows()
print("file" + filename + ".jpg is resize finish")
def Mutil(oripath):
for file in os.listdir(oripath):
# print(oripath + file)
img, pts1, pts2, filename, width, heigh = ReadIM(oripath, file)
Resize(img, pts1, pts2, filename, width, heigh)
def ReadIM(oripath, file):
file1 = file.replace(").jpg", "")
p = re.search("\(", file).span()
# print(p)
filename = file1[:p[1]-1]
# print(filename)
points = file1[p[1]:].split("),(")
print(points)
# print(points)
pts1 = []
for x in points:
pts1.append([float(x.split(",")[0]), float(x.split(",")[1])])
# print(pts1)
width = pts1[1][0] - pts1[0][0] if pts1[1][0] - pts1[0][0] > pts1[2][0] - pts1[3][0] else pts1[2][0] - pts1[3][0]
heigh = pts1[3][1] - pts1[0][1] if pts1[3][1] - pts1[0][1] > pts1[2][1] - pts1[1][1] else pts1[2][1] - pts1[1][1]
pts1 = np.array(pts1, dtype=float).astype(np.float32)
img = cv2.imread(oripath + file)
pts2 = np.float32([[0, 0], [width, 0], [width, heigh], [0, heigh]])
return img, pts1, pts2, filename, width, heigh
# 同时处理一个文件夹中的图片
# Mutil(oripath)
# 单独处理某一张图片
img, pts1, pts2, filename, width, heigh = ReadIM(oripath, "test_1(356, 66),(498, 80),(428, 630),(272, 600).jpg")
Resize(img, pts1, pts2, filename, width, heigh)
# Getpoint.py
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 8 16:03:04 2020
@author: 褚凡
"""
import cv2
import os
#图片路径
oripath = "C:\\Users\\Administrator\\Desktop\\picture\\"
num = 0
for file in os.listdir(oripath):
if file.endswith(".jpg"):
num += 1
img = cv2.imread(oripath + file)
a = []
def on_EVENT_LBUTTONDOWN(event, x, y,flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
xy = "%d,%d" % (x, y)
a.append([x, y])
cv2.circle(img, (x, y), 1, (0, 0, 255), thickness=-1)
cv2.putText(img, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,
1.0, (0, 0, 0), thickness=1)
cv2.imshow("image", img)
cv2.namedWindow("image", 0)
cv2.setMouseCallback("image", on_EVENT_LBUTTONDOWN)
cv2.resizeWindow("image", int(img.shape[1]/2), int(img.shape[0]/2));
cv2.imshow("image", img)
cv2.waitKey(0)
print(a)
filename = str(a).replace("[[", "(").replace("], [","),(").replace("]]",")")
os.rename(oripath + file, oripath + 'test_' + str(num) + filename + '.jpg')
else:
pass
大概就是这样,溜了溜了
有问题留言哈