網(wǎng)站首頁 編程語言 正文
本文實例為大家分享了Python Opencv基于透視變換的圖像矯正,供大家參考,具體內(nèi)容如下
一、自動獲取圖像頂點變換(獲取圖像輪廓頂點矯正)
圖像旋轉(zhuǎn)校正思路如下
1、以灰度圖讀入
2、腐蝕膨脹,閉合等操作
3、二值化圖像
4、獲取圖像頂點
5、透視矯正
#(基于透視的圖像矯正) import cv2 import math import numpy as np def Img_Outline(input_dir): ? ? original_img = cv2.imread(input_dir) ? ? gray_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY) ? ? blurred = cv2.GaussianBlur(gray_img, (9, 9), 0) ? ? ? ? ? ? ? ? ? ? # 高斯模糊去噪(設(shè)定卷積核大小影響效果) ? ? _, RedThresh = cv2.threshold(blurred, 165, 255, cv2.THRESH_BINARY) ?# 設(shè)定閾值165(閾值影響開閉運算效果) ? ? kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) ? ? ? ? ?# 定義矩形結(jié)構(gòu)元素 ? ? closed = cv2.morphologyEx(RedThresh, cv2.MORPH_CLOSE, kernel) ? ? ? # 閉運算(鏈接塊) ? ? opened = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel) ? ? ? ? ? # 開運算(去噪點) ? ? return original_img, gray_img, RedThresh, closed, opened def findContours_img(original_img, opened): ? ? image, contours, hierarchy = cv2.findContours(opened, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) ? ? c = sorted(contours, key=cv2.contourArea, reverse=True)[1] ? # 計算最大輪廓的旋轉(zhuǎn)包圍盒 ? ? rect = cv2.minAreaRect(c) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 獲取包圍盒(中心點,寬高,旋轉(zhuǎn)角度) ? ? box = np.int0(cv2.boxPoints(rect)) ? ? ? ? ? ? ? ? ? ? ? ? ? # box ? ? draw_img = cv2.drawContours(original_img.copy(), [box], -1, (0, 0, 255), 3) ? ? print("box[0]:", box[0]) ? ? print("box[1]:", box[1]) ? ? print("box[2]:", box[2]) ? ? print("box[3]:", box[3]) ? ? return box,draw_img def Perspective_transform(box,original_img): ? ? # 獲取畫框?qū)捀?x=orignal_W,y=orignal_H) ? ? orignal_W = math.ceil(np.sqrt((box[3][1] - box[2][1])**2 + (box[3][0] - box[2][0])**2)) ? ? orignal_H= math.ceil(np.sqrt((box[3][1] - box[0][1])**2 + (box[3][0] - box[0][0])**2)) ? ? # 原圖中的四個頂點,與變換矩陣 ? ? pts1 = np.float32([box[0], box[1], box[2], box[3]]) ? ? pts2 = np.float32([[int(orignal_W+1),int(orignal_H+1)], [0, int(orignal_H+1)], [0, 0], [int(orignal_W+1), 0]]) ? ? # 生成透視變換矩陣;進行透視變換 ? ? M = cv2.getPerspectiveTransform(pts1, pts2) ? ? result_img = cv2.warpPerspective(original_img, M, (int(orignal_W+3),int(orignal_H+1))) ? ? return result_img if __name__=="__main__": ? ? input_dir = "../staticimg/oldimg_04.jpg" ? ? original_img, gray_img, RedThresh, closed, opened = Img_Outline(input_dir) ? ? box, draw_img = findContours_img(original_img,opened) ? ? result_img = Perspective_transform(box,original_img) ? ? cv2.imshow("original", original_img) ? ? cv2.imshow("gray", gray_img) ? ? cv2.imshow("closed", closed) ? ? cv2.imshow("opened", opened) ? ? cv2.imshow("draw_img", draw_img) ? ? cv2.imshow("result_img", result_img) ? ? cv2.waitKey(0) ? ? cv2.destroyAllWindows()
直接變換
1、獲取圖像四個頂點
2、形成變換矩陣
3、透視變換
import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('original_img.jpg') H_rows, W_cols= img.shape[:2] print(H_rows, W_cols) # 原圖中書本的四個角點(左上、右上、左下、右下),與變換后矩陣位置 pts1 = np.float32([[161, 80], [449, 12], [1, 430], [480, 394]]) pts2 = np.float32([[0, 0],[W_cols,0],[0, H_rows],[H_rows,W_cols],]) # 生成透視變換矩陣;進行透視變換 M = cv2.getPerspectiveTransform(pts1, pts2) dst = cv2.warpPerspective(img, M, (500,470)) """ 注釋代碼同效 # img[:, :, ::-1]是將BGR轉(zhuǎn)化為RGB # plt.subplot(121), plt.imshow(img[:, :, ::-1]), plt.title('input') # plt.subplot(122), plt.imshow(dst[:, :, ::-1]), plt.title('output') # plt.show """ cv2.imshow("original_img",img) cv2.imshow("result",dst) cv2.waitKey(0) cv2.destroyAllWindows()
兩次透視變換
def get_warp_perspective(img, width, height, array_points, array_points_get, array_points_warp): ? ? middle_len = 268 ? ? # rows, cols = img.shape[:2] ? ? # D_value1 = (middle_len - array_points_get[0][1])*2+((middle_len - array_points_get[0][1])//3) ? ? # D_value2 = (middle_len - array_points_get[1][1])*2+((middle_len - array_points_get[1][1])//3) ? ? D_value1 = 0 ? ? D_value2 = 0 ? ? # 原圖中的四個角點 ? ? # pts1 = np.float32([[0, 249],[512, 253],[0, 512], [512, 512]])#重要的測試1和2 ? ? pts1 = np.float32(array_points_get)#重要的測試1和2 ? ? # pts2 = np.float32([[0, middle_len], [width, middle_len], [0, height], [width, height]])#重要的測試1和2 ? ? # pts2 = np.float32([[0, middle_len],[0, height] , [width, height],[width, middle_len]])#重要的測試1和2 ? ? pts2 = np.float32([[0, 0],[0, middle_len] , [width, middle_len],[width, 0]])#重要的測試1和2 ? ? # 生成透視變換矩陣 ? ? M = cv2.getPerspectiveTransform(pts1, pts2) ? ? # 進行透視變換 ? ? dst = cv2.warpPerspective(img, M, (width, height)) ? ? # # 保存圖片,僅用于測試 ? ? img_path = './cut_labels/cut_image_one.jpg' ? ? cv2.imwrite(img_path, dst) ? ? return warp_perspective(dst, width, height,array_points,array_points_warp,middle_len, D_value1, D_value2) def warp_perspective(dst, width, height,array_points,array_points_warp,middle_len, D_value1, D_value2): ? ? # new_img_path = img_path ? ? # img = cv2.imread(new_img_path) ? ? # 原圖的保存地址 ? ? # rows, cols = img.shape[:2] ? ? # 原圖中的四個角點 ? ? # pts3 = np.float32([[0, 268], [0, 44], [512,35], [512, 268]])#重要測試1 ? ? # pts3 = np.float32([[0, middle_len], [0, D_value1], [512,D_value2], [512, middle_len]])#重要測試1 ? ? pts3 = np.float32([[0, 0], [0, height], [width, height], [width, 0]]) ? ? # pts3 = np.float32([[0, middle_len], [0, D_value1], [512,D_value2], [512, middle_len]])#重要測試1 ? ? # pts3 = np.float32([[0, 512], [0, array_points[1][1]], [512,512], [512, middle_len]])#重要測試1 ? ? # 變換后的四個角點 ? ? pts4 = np.float32([[0, 0], [0, height-D_value1], [width, height-D_value2], [width, 0]])#重要測試1 ? ? # pts4 = np.float32([[0, 268], [0, 0], [512, 0], [512, 268]])#重要測試1 ? ? # 生成透視變換矩陣 ? ? M = cv2.getPerspectiveTransform(pts3, pts4) ? ? # 進行透視變換 ? ? dst_img = cv2.warpPerspective(dst, M, (width, height)) ? ? # #保存最終圖片,僅用于測試 ? ? print("++++++++++++++++") ? ? final_img_path = './cut_labels/cut_image_two.jpg' ? ? cv2.imwrite(final_img_path, dst_img) ? ? # 進行透視變換 ? ? return cv2.warpPerspective(dst_img, M, (width, height)) ? ? # return output_warp_perspective(img, width, height, array_points, array_points_get, array_points_warp) if __name__ ?== "__main__": ?? ?# 透視轉(zhuǎn)換 ? ?? ? img = cv2.imread('../staticimg/oldimg_04.jpg') ? ? ?dst = get_warp_perspective(img, 512, 512, array_points=[[395.2, 75.0], [342, 517], [1000, 502], [900, 75]]) ? ? ?cv2.imwrite('aaa2.jpg', dst) ? ? ?cv2.imshow('title', dst) ? ? ?cv2.waitKey(0) ? ? ?imgrectificate = imgRectificate(img, width, height, array_points) ? ? ?imgrectificate.warp_perspective()
原文鏈接:https://blog.csdn.net/weixin_43431189/article/details/93513923
相關(guān)推薦
- 2021-12-10 Ubuntu環(huán)境下mongodb安裝配置詳細(xì)步驟_MongoDB
- 2022-07-28 C++超詳細(xì)講解強制類型轉(zhuǎn)換_C 語言
- 2022-07-11 Sonatype Nexus搭建Maven私服
- 2024-04-07 MyBatis批量插入的五種方式(推薦MyBatis以集合方式批量新增)
- 2022-05-15 Qt windows打開資源管理器并高亮文件
- 2024-03-15 docker刪除、停止所有容器或鏡像
- 2022-02-25 Oracle工具PL/SQL的基本語法_oracle
- 2022-02-27 Error in render: “TypeError: Cannot read propertie
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支