Python?Opencv基于透視變換的圖像矯正
本文實(shí)例為大家分享了Python Opencv基于透視變換的圖像矯正,供大家參考,具體內(nèi)容如下
一、自動(dòng)獲取圖像頂點(diǎn)變換(獲取圖像輪廓頂點(diǎn)矯正)
圖像旋轉(zhuǎn)校正思路如下
1、以灰度圖讀入
2、腐蝕膨脹,閉合等操作
3、二值化圖像
4、獲取圖像頂點(diǎn)
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(閾值影響開(kāi)閉運(yùn)算效果)
? ? kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) ? ? ? ? ?# 定義矩形結(jié)構(gòu)元素
? ? closed = cv2.morphologyEx(RedThresh, cv2.MORPH_CLOSE, kernel) ? ? ? # 閉運(yùn)算(鏈接塊)
? ? opened = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel) ? ? ? ? ? # 開(kāi)運(yùn)算(去噪點(diǎn))
? ? 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] ? # 計(jì)算最大輪廓的旋轉(zhuǎn)包圍盒
? ? rect = cv2.minAreaRect(c) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 獲取包圍盒(中心點(diǎn),寬高,旋轉(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):
? ? # 獲取畫(huà)框?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))
? ? # 原圖中的四個(gè)頂點(diǎn),與變換矩陣
? ? 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]])
? ? # 生成透視變換矩陣;進(jìn)行透視變換
? ? 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、獲取圖像四個(gè)頂點(diǎn)
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)
# 原圖中書(shū)本的四個(gè)角點(diǎn)(左上、右上、左下、右下),與變換后矩陣位置
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],])
# 生成透視變換矩陣;進(jìn)行透視變換
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
? ? # 原圖中的四個(gè)角點(diǎn)
? ? # pts1 = np.float32([[0, 249],[512, 253],[0, 512], [512, 512]])#重要的測(cè)試1和2
? ? pts1 = np.float32(array_points_get)#重要的測(cè)試1和2
? ? # pts2 = np.float32([[0, middle_len], [width, middle_len], [0, height], [width, height]])#重要的測(cè)試1和2
? ? # pts2 = np.float32([[0, middle_len],[0, height] , [width, height],[width, middle_len]])#重要的測(cè)試1和2
? ? pts2 = np.float32([[0, 0],[0, middle_len] , [width, middle_len],[width, 0]])#重要的測(cè)試1和2
? ? # 生成透視變換矩陣
? ? M = cv2.getPerspectiveTransform(pts1, pts2)
? ? # 進(jìn)行透視變換
? ? dst = cv2.warpPerspective(img, M, (width, height))
? ? # # 保存圖片,僅用于測(cè)試
? ? 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]
? ? # 原圖中的四個(gè)角點(diǎn)
? ? # pts3 = np.float32([[0, 268], [0, 44], [512,35], [512, 268]])#重要測(cè)試1
? ? # pts3 = np.float32([[0, middle_len], [0, D_value1], [512,D_value2], [512, middle_len]])#重要測(cè)試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]])#重要測(cè)試1
? ? # pts3 = np.float32([[0, 512], [0, array_points[1][1]], [512,512], [512, middle_len]])#重要測(cè)試1
? ? # 變換后的四個(gè)角點(diǎn)
? ? pts4 = np.float32([[0, 0], [0, height-D_value1], [width, height-D_value2], [width, 0]])#重要測(cè)試1
? ? # pts4 = np.float32([[0, 268], [0, 0], [512, 0], [512, 268]])#重要測(cè)試1
? ? # 生成透視變換矩陣
? ? M = cv2.getPerspectiveTransform(pts3, pts4)
? ? # 進(jìn)行透視變換
? ? dst_img = cv2.warpPerspective(dst, M, (width, height))
? ? # #保存最終圖片,僅用于測(cè)試
? ? print("++++++++++++++++")
? ? final_img_path = './cut_labels/cut_image_two.jpg'
? ? cv2.imwrite(final_img_path, dst_img)
? ? # 進(jìn)行透視變換
? ? 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()以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- OpenCV通過(guò)透視變換實(shí)現(xiàn)矯正圖像詳解
- Java OpenCV圖像處理之仿射變換,透視變換,旋轉(zhuǎn)詳解
- OpenCV透視變換應(yīng)用之書(shū)本視圖矯正+廣告屏幕切換
- Python?OpenCV超詳細(xì)講解透視變換的實(shí)現(xiàn)
- OpenCV實(shí)現(xiàn)透視變換矯正
- 詳解如何在pyqt中通過(guò)OpenCV實(shí)現(xiàn)對(duì)窗口的透視變換
- opencv3/C++ 平面對(duì)象識(shí)別&透視變換方式
- OpenCV圖像幾何變換之透視變換
- Opencv透視變換綜合實(shí)例詳解
- OpenCV實(shí)現(xiàn)透視變換的示例代碼
相關(guān)文章
python基礎(chǔ)教程項(xiàng)目五之虛擬茶話會(huì)
這篇文章主要為大家詳細(xì)介紹了python基礎(chǔ)教程項(xiàng)目五之虛擬茶話會(huì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
Python中*args和**kwargs的區(qū)別詳解
這篇文章主要介紹了Python中*args和**kwargs的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
穩(wěn)扎穩(wěn)打?qū)WPython之容器 可迭代對(duì)象 迭代器 生成器專題講解
在剛開(kāi)始學(xué)Python的時(shí)候,是不是經(jīng)常會(huì)聽(tīng)到大佬們?cè)谥v容器、可迭代對(duì)象、迭代器、生成器、列表/集合/字典推導(dǎo)式等等眾多概念,其實(shí)這不是大佬們沒(méi)事就擱那扯專業(yè)術(shù)語(yǔ)來(lái)裝B,而是這些東西都得要明白的,光知道字符串、列表等基礎(chǔ)還是不夠的,尤其是在Python的數(shù)據(jù)結(jié)構(gòu)方面2021-10-10
Python函數(shù)必須先定義,后調(diào)用說(shuō)明(函數(shù)調(diào)用函數(shù)例外)
這篇文章主要介紹了Python函數(shù)必須先定義,后調(diào)用說(shuō)明(函數(shù)調(diào)用函數(shù)例外),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
Python機(jī)器學(xué)習(xí)應(yīng)用之工業(yè)蒸汽數(shù)據(jù)分析篇詳解
本篇文章介紹了如何用Python進(jìn)行工業(yè)蒸汽數(shù)據(jù)分析的過(guò)程及思路,通讀本篇對(duì)大家的學(xué)習(xí)或工作具有一定的價(jià)值,需要的朋友可以參考下2022-01-01
Python中識(shí)別圖片/滑塊驗(yàn)證碼準(zhǔn)確率極高的ddddocr庫(kù)詳解
驗(yàn)證碼的種類有很多,它是常用的一種反爬手段,包括:圖片驗(yàn)證碼,滑塊驗(yàn)證碼,等一些常見(jiàn)的驗(yàn)證碼場(chǎng)景。這里推薦一個(gè)簡(jiǎn)單實(shí)用的識(shí)別驗(yàn)證碼的庫(kù)?ddddocr?(帶帶弟弟ocr)庫(kù),希望大家喜歡2023-02-02
一篇文章帶你了解Python之Selenium自動(dòng)化爬蟲(chóng)
這篇文章主要為大家詳細(xì)介紹了Python之Selenium自動(dòng)化爬蟲(chóng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-01-01
Python時(shí)間處理模塊Time和DateTime
這篇文章主要為大家介紹了Python時(shí)間處理模塊Time和DateTime使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06

