前言
日常生活中,手殘黨們經(jīng)常會(huì)把一些照片拍歪,比如拍個(gè)證件、試卷、PPT什么的,
比如下面這本書的封面原本是個(gè)矩形,隨手一拍就成了不規(guī)則四邊形
想要把它變成規(guī)則的矩形,有什么辦法呢?
你一定想到了 PS,因?yàn)榫W(wǎng)上很多教程就是這么教的
打開PS
可是這樣手工的調(diào)整數(shù)值實(shí)在是費(fèi)勁喲!!
下面我們來寫個(gè)程序,自動(dòng)將圖片恢復(fù)到任意矩形!
程序?qū)崿F(xiàn)
1. 打開圖片并顯示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import cv2 as cv import numpy as np path = './book.jpg' src = cv.imread(path) 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) h, w = get_window_size(src) win_name = 'RecAdjust' 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() |
2. 在圖片中標(biāo)記四個(gè)角點(diǎn)
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
|
src_copy = src.copy() class Indexer: def __init__( self , bound = 4 ): self . id = 0 self .bound = bound def get_id( self ): self . id = ( self . id + 1 ) % self .bound return ( self . id - 1 ) % self .bound + 1 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 ( '第{}個(gè)頂點(diǎn): ({},{})' . format (curr_id, x, y)) cv.circle(img, (x, y), 10 , ( 0 , 0 , 255 ), thickness = 2 ) cv.putText( img, str (curr_id), # 文字 (x, y), # 坐標(biāo) cv.FONT_HERSHEY_PLAIN, 5 , # 字號(hào) ( 0 , 0 , 255 ), # 字體顏色 thickness = 2 # 粗細(xì) ) cv.imshow(win_name, img) points = [] indexer = Indexer() win_name = 'RecAdjust' 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() print (points) |
3. 設(shè)定輸出矩形大小
1
2
3
4
|
# W = int(input('輸出圖片寬度:')) # H = int(input('輸出圖片高度:')) W,H = 600 , 800 target_points = [( 0 , 0 ),(W, 0 ),(W,H),( 0 ,H)] |
4. 求解透視變換矩陣
1
2
3
|
points, target_points = np.array(points, dtype = np.float32), np.array(target_points, dtype = np.float32) M = cv.getPerspectiveTransform(points, target_points) print ( '透視變換矩陣:' ,M) |
5. 透視變換并保存圖片
1
2
3
4
5
6
7
8
9
10
11
|
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() output_file = 'result.jpg' cv.imwrite(output_file, result) |
結(jié)果如下
結(jié)果沒有想象的完美,是因?yàn)闀姆饷嬉呀?jīng)不是一個(gè)平面了,書角翹起。。。
如果圖片中的矩形在一個(gè)平面上的話,效果還是挺不錯(cuò)的!!
完整代碼下載
可關(guān)注后免費(fèi)下載喔:https://download.csdn.net/download/itnerd/12819535
總結(jié)
到此這篇關(guān)于利用Python將圖片中扭曲矩形復(fù)原的文章就介紹到這了,更多相關(guān)Python圖片扭曲矩形復(fù)原內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://blog.csdn.net/itnerd/article/details/108429553