一、操作流程
首先复制代码会吧?
1.有张照片
这是网上随便找的一张照片,自行保存测试
2.看看照片
运行代码,其中show_img函数是展示照片
3.选择角点
按照左上,右上,右下,左下的顺序选择四个角点
如果担心自己选不好,可以直接去除我代码里的points的注释,那是我自己用的原版
4.最终结果
二、代码分析
import 没什么好说的
1
2
3
|
#如果python没有安装cv2,那么就安装python-opencv就好
import cv2 as cv
import numpy as np
|
获取图片的长宽
1
2
3
4
5
6
7
8
|
#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分
def get_window_size(src, bound = 600 ):
h,w = src.shape[ 0 ], src.shape[ 1 ]
if h > w:
h, w = bound, int (w * bound / h)
else :
h, w = int (h * bound / w), bound
return (h, w)
|
通过鼠标获取图片的坐标点,顺序是左上,右上,右下,左下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
class indexer:
def __init__( self , bound = 4 ):
self . id = 0
self .bound = bound
def get_id( self ):
self . id = ( self . id + 1 )
return ( self . id )
def on_event_lbuttondown(event, x, y, flags, param):
if event = = cv.event_lbuttondown:
img = param[ 'src' ]
win_name = param[ 'window' ]
indexer = param[ 'indexer' ]
points = param[ 'points' ]
curr_id = indexer.get_id()
points.append((x, y))
print ( '第{}个顶点: ({},{})' . format (curr_id, x, y))
cv.circle(img, (x, y), 10 , ( 0 , 0 , 255 ), thickness = 2 )
cv.puttext(
img,
str (curr_id), # 文字
(x, y), # 坐标
cv.font_hershey_plain,
5 , # 字号
( 0 , 0 , 255 ), # 字体颜色
thickness = 2 # 粗细
)
cv.imshow(win_name, img)
#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分
def get_points(src):
points = []
indexer = indexer()
h, w = get_window_size(src)
win_name = 'get_points'
cv.namedwindow(win_name, cv.window_normal)
cv.resizewindow(win_name, width = w, height = h)
cv.imshow(win_name, src)
cv.setmousecallback(win_name, on_event_lbuttondown,
param = { 'src' : src, 'window' : win_name, 'indexer' : indexer, 'points' : points})
cv.waitkey( 0 )
cv.destroyallwindows()
if len (points)> 4 :
return points[ 0 : 4 ]
# print(points)
# points=[(2, 14), (90, 50), (87, 194), (1, 204)]
return points
#输入cv.imread后的图片,展示图片长什么样
def show_img(src):
win_name = 'show_img'
h, w = get_window_size(src)
cv.namedwindow(win_name, cv.window_normal)
cv.resizewindow(win_name, width = w, height = h)
cv.imshow(win_name, src)
cv.waitkey( 0 )
cv.destroyallwindows()
|
将图片截取,并按照指定的长宽比恢复成矩形
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def photo_cut_restore(src,points,h,w):
target_points = [( 0 , 0 ), (w, 0 ), (w, h), ( 0 , h)]
points, target_points = np.array(points, dtype = np.float32), np.array(target_points, dtype = np.float32)
m = cv.getperspectivetransform(points, target_points)
# print('透视变换矩阵:', m)
result = cv.warpperspective(src_copy, m, ( 0 , 0 ))
result = result[:h, :w]
win_name = 'result'
cv.namedwindow(win_name, cv.window_normal)
cv.resizewindow(win_name, width = w, height = h)
cv.imshow(win_name,result)
cv.waitkey( 0 )
cv.destroyallwindows()
return result
|
主程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
if __name__ = = '__main__' :
path = './1.jpg'
src = cv.imread(path)
src_copy = src.copy()
show_img(src)
w = 20
h = 20
# points=[(112, 308), (175, 310), (176, 369), (113, 369)]
points = get_points(src)
n = 20
w = int (w * n)
h = int (h * n)
result = photo_cut_restore(src_copy,points,h,w)
output_file = 'result.jpg'
cv.imwrite(output_file, result)
|
三、懒人一键复制代码
诶,气不气,好不容易一段段复制完,结果最后居然有一键复制的地方
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
import cv2 as cv
import numpy as np
#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分
def get_window_size(src, bound = 600 ):
h,w = src.shape[ 0 ], src.shape[ 1 ]
if h > w:
h, w = bound, int (w * bound / h)
else :
h, w = int (h * bound / w), bound
return (h, w)
class indexer:
def __init__( self ):
self . id = 0
def get_id( self ):
self . id = ( self . id + 1 )
return ( self . id )
def on_event_lbuttondown(event, x, y, flags, param):
if event = = cv.event_lbuttondown:
img = param[ 'src' ]
win_name = param[ 'window' ]
indexer = param[ 'indexer' ]
points = param[ 'points' ]
curr_id = indexer.get_id()
points.append((x, y))
print ( '第{}个顶点: ({},{})' . format (curr_id, x, y))
cv.circle(img, (x, y), 10 , ( 0 , 0 , 255 ), thickness = 2 )
cv.puttext(
img,
str (curr_id), # 文字
(x, y), # 坐标
cv.font_hershey_plain,
5 , # 字号
( 0 , 0 , 255 ), # 字体颜色
thickness = 2 # 粗细
)
cv.imshow(win_name, img)
#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分
def get_points(src):
points = []
indexer = indexer()
h, w = get_window_size(src)
win_name = 'get_points'
cv.namedwindow(win_name, cv.window_normal)
cv.resizewindow(win_name, width = w, height = h)
cv.imshow(win_name, src)
cv.setmousecallback(win_name, on_event_lbuttondown,
param = { 'src' : src, 'window' : win_name, 'indexer' : indexer, 'points' : points})
cv.waitkey( 0 )
cv.destroyallwindows()
if len (points)> 4 :
return points[ 0 : 4 ]
# print(points)
# points=[(2, 14), (90, 50), (87, 194), (1, 204)]
return points
#输入cv.imread后的图片,展示图片长什么样
def show_img(src):
win_name = 'show_img'
h, w = get_window_size(src)
cv.namedwindow(win_name, cv.window_normal)
cv.resizewindow(win_name, width = w, height = h)
cv.imshow(win_name, src)
cv.waitkey( 0 )
cv.destroyallwindows()
def photo_cut_restore(src,points,h,w):
target_points = [( 0 , 0 ), (w, 0 ), (w, h), ( 0 , h)]
points, target_points = np.array(points, dtype = np.float32), np.array(target_points, dtype = np.float32)
m = cv.getperspectivetransform(points, target_points)
# print('透视变换矩阵:', m)
result = cv.warpperspective(src_copy, m, ( 0 , 0 ))
result = result[:h, :w]
win_name = 'result'
cv.namedwindow(win_name, cv.window_normal)
cv.resizewindow(win_name, width = w, height = h)
cv.imshow(win_name,result)
cv.waitkey( 0 )
cv.destroyallwindows()
return result
if __name__ = = '__main__' :
path = './3.jpg'
src = cv.imread(path)
src_copy = src.copy()
# show_img(src)
w = 20
h = 20
# points=[(124, 182), (181, 177), (180, 243), (125, 266)]
points = get_points(src)
print (points)
n = 20
w = int (w * n)
h = int (h * n)
result = photo_cut_restore(src_copy,points,h,w)
output_file = 'result.jpg'
cv.imwrite(output_file, result)
|
到此这篇关于python图片处理之图片裁剪教程的文章就介绍到这了,更多相关python图片裁剪内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/weixin_43958086/article/details/117250288