Python圖片處理之圖片裁剪教程
一、操作流程
首先復(fù)制代碼會吧?
1.有張照片
這是網(wǎng)上隨便找的一張照片,自行保存測試

2.看看照片
運行代碼,其中show_img函數(shù)是展示照片
3.選擇角點
按照左上,右上,右下,左下的順序選擇四個角點

如果擔(dān)心自己選不好,可以直接去除我代碼里的points的注釋,那是我自己用的原版
4.最終結(jié)果

二、代碼分析
import 沒什么好說的
#如果python沒有安裝cv2,那么就安裝python-opencv就好 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, 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()
將圖片截取,并按照指定的長寬比恢復(fù)成矩形
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 = './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)
三、懶人一鍵復(fù)制代碼
誒,氣不氣,好不容易一段段復(fù)制完,結(jié)果最后居然有一鍵復(fù)制的地方
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)
到此這篇關(guān)于Python圖片處理之圖片裁剪教程的文章就介紹到這了,更多相關(guān)Python圖片裁剪內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
TensorFlow安裝及jupyter notebook配置方法
下面小編就為大家?guī)硪黄猅ensorFlow安裝及jupyter notebook配置方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
python2 與python3的print區(qū)別小結(jié)
這篇文章主要介紹了python2 與python3的print區(qū)別小結(jié),需要的朋友可以參考下2018-01-01
Python實現(xiàn)向QQ群成員自動發(fā)郵件的方法
這篇文章主要介紹了Python實現(xiàn)向QQ群成員自動發(fā)郵件的方法,通過讀取txt文本里的QQ成員數(shù)據(jù)再調(diào)用發(fā)送郵件函數(shù)實現(xiàn)該功能,是非常實用的技巧,需要的朋友可以參考下2014-11-11
tensorflow指定CPU與GPU運算的方法實現(xiàn)
這篇文章主要介紹了tensorflow指定CPU與GPU運算的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Python數(shù)據(jù)類型之Tuple元組實例詳解
這篇文章主要介紹了Python數(shù)據(jù)類型之Tuple元組,結(jié)合實例形式分析了Python元組類型的概念、定義、讀取、連接、判斷等常見操作技巧與相關(guān)注意事項,需要的朋友可以參考下2019-05-05
python將三維數(shù)組展開成二維數(shù)組的實現(xiàn)
今天小編就為大家分享一篇python將三維數(shù)組展開成二維數(shù)組的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
使用Pytest.main()運行時參數(shù)不生效問題解決
本文主要介紹了使用Pytest.main()運行時參數(shù)不生效問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02

