OpenCV實(shí)戰(zhàn)之圖像拼接的示例代碼
背景
圖像拼接可以應(yīng)用到手機(jī)中的全景拍攝,也就是將多張圖片根據(jù)關(guān)聯(lián)信息拼成一張圖片;
實(shí)現(xiàn)步驟
1、讀文件并縮放圖片大小;
2、根據(jù)特征點(diǎn)和計(jì)算描述子,得到單應(yīng)性矩陣;
3、根據(jù)單應(yīng)性矩陣對(duì)圖像進(jìn)行變換,然后平移;
4、圖像拼接并輸出拼接后結(jié)果圖;
一、讀取文件
第一步實(shí)現(xiàn)讀取兩張圖片并縮放到相同尺寸;
代碼如下:
img1 = cv2.imread('map1.png') img2 = cv2.imread('map2.png') img1 = cv2.resize(img1, (640, 480)) img2 = cv2.resize(img2, (640, 480)) input = np.hstack((img1, img2)) cv2.imshow('input', input) cv2.waitKey(0)
上圖為我們需要拼接的兩張圖的展示,可以看出其還具有一定的旋轉(zhuǎn)變換,之后的圖像轉(zhuǎn)換必定包含旋轉(zhuǎn)的操作;
二、單應(yīng)性矩陣計(jì)算
主要分為以下幾個(gè)步驟:
1、創(chuàng)建特征轉(zhuǎn)換對(duì)象;
2、通過(guò)特征轉(zhuǎn)換對(duì)象獲得特征點(diǎn)和描述子;
3、創(chuàng)建特征匹配器;
4、進(jìn)行特征匹配;
5、過(guò)濾特征,找出有效的特征匹配點(diǎn);
6、單應(yīng)性矩陣計(jì)算
實(shí)現(xiàn)代碼:
def get_homo(img1, img2): ? ? # 1實(shí)現(xiàn) ? ? sift = cv2.xfeatures2d.SIFT_create() ? ? # 2實(shí)現(xiàn) ? ? k1, p1 = sift.detectAndCompute(img1, None) ? ? k2, p2 = sift.detectAndCompute(img2, None) ? ? # 3實(shí)現(xiàn) ? ? bf = cv2.BFMatcher() ? ? # 4實(shí)現(xiàn) ? ? matches = bf.knnMatch(p1, p2, k=2) ? ? # 5實(shí)現(xiàn) ? ? good = [] ? ? for m1, m2 in matches: ? ? ? ? if m1.distance < 0.8 * m2.distance: ? ? ? ? ? ? good.append(m1) ? ? # 6實(shí)現(xiàn) ? ? if len(good) > 8: ? ? ? ? img1_pts = [] ? ? ? ? img2_pts = [] ? ? ? ? for m in good: ? ? ? ? ? ? img1_pts.append(k1[m.queryIdx].pt) ? ? ? ? ? ? img2_pts.append(k2[m.trainIdx].pt) ? ? ? ? img1_pts = np.float32(img1_pts).reshape(-1, 1, 2) ? ? ? ? img2_pts = np.float32(img2_pts).reshape(-1, 1, 2) ? ? ? ? H, mask = cv2.findHomography(img1_pts, img2_pts, cv2.RANSAC, 5.0) ? ? ? ? return H ? ? else: ? ? ? ? print('piints is not enough 8!') ? ? ? ? exit()
三、圖像拼接
實(shí)現(xiàn)步驟:
1、獲得圖像的四個(gè)角點(diǎn);
2、根據(jù)單應(yīng)性矩陣變換圖片;
3、創(chuàng)建一張大圖,拼接圖像;
4、輸出結(jié)果
實(shí)現(xiàn)代碼:
def stitch_img(img1, img2, H): ? ? # 1實(shí)現(xiàn) ? ? h1, w1 = img1.shape[:2] ? ? h2, w2 = img2.shape[:2] ? ? img1_point = np.float32([[0,0], [0,h1], [w1,h1], [w1,0]]).reshape(-1, 1, 2) ? ? img2_point = np.float32([[0,0], [0,h2], [w2,h2], [w2,0]]).reshape(-1, 1, 2) ? ? # 2實(shí)現(xiàn) ? ? img1_trans = cv2.perspectiveTransform(img1_point, H) ? ? # 將img1變換后的角點(diǎn)與img2原來(lái)的角點(diǎn)做拼接 ? ? result_point = np.concatenate((img2_point, img1_trans), axis=0) ? ? # 獲得拼接后圖像x,y的最小值 ? ? [x_min, y_min] = np.int32(result_point.min(axis=0).ravel()-0.5) ? ? # 獲得拼接后圖像x,y的最大值 ? ? [x_max, y_max] = np.int32(result_point.max(axis=0).ravel()+0.5) ? ? # 平移距離 ? ? trans_dist = [-x_min, -y_min] ? ? # 構(gòu)建一個(gè)齊次平移矩陣 ? ? trans_array = np.array([[1, 0, trans_dist[0]], ? ? ? ? ? ? ? ? ? ? ? ? ? ? [0, 1, trans_dist[1]], ? ? ? ? ? ? ? ? ? ? ? ? ? ? [0, 0, 1]]) ? ? # 平移和單應(yīng)性變換 ? ? res_img = cv2.warpPerspective(img1, trans_array.dot(H), (x_max-x_min, y_max-y_min)) ? ? # 3實(shí)現(xiàn) ? ? res_img[trans_dist[1]:trans_dist[1]+h2, ? ? ? ? ? ? trans_dist[0]:trans_dist[0]+w2] = img2 ? ? return res_img H = get_homo(img1, img2) res_img = stitch_img(img1, img2, H) # 4實(shí)現(xiàn) cv2.imshow('result', res_img) cv2.waitKey(0)?
最終結(jié)果圖如上圖所示,還有待優(yōu)化點(diǎn)如下:
- 邊緣部分有色差,可以根據(jù)取平均值消除;
- 黑色區(qū)域可進(jìn)行裁剪并用對(duì)應(yīng)顏色填充;
優(yōu)化部分難度不大,有興趣的可以實(shí)現(xiàn)一下;
總結(jié)
圖像拼接作為一個(gè)實(shí)用性技術(shù)經(jīng)常出現(xiàn)在我們的生活中,特別是全景拍攝以及圖像內(nèi)容拼接;當(dāng)然,基于傳統(tǒng)算法的圖像拼接還是會(huì)有一些缺陷(速度和效果上),感興趣的可以了解下基于深度學(xué)習(xí)的圖像拼接算法,期待和大家溝通!
到此這篇關(guān)于OpenCV實(shí)戰(zhàn)之圖像拼接的示例代碼的文章就介紹到這了,更多相關(guān)OpenCV圖像拼接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pytorch 擴(kuò)展Tensor維度、壓縮Tensor維度的方法
這篇文章主要介紹了Pytorch 擴(kuò)展Tensor維度、壓縮Tensor維度的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09解決Python安裝cryptography報(bào)錯(cuò)問(wèn)題
這篇文章主要介紹了解決Python安裝cryptography報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09Python中的高級(jí)數(shù)據(jù)結(jié)構(gòu)詳解
這篇文章主要介紹了Python中的高級(jí)數(shù)據(jù)結(jié)構(gòu)詳解,本文講解了Collection、Array、Heapq、Bisect、Weakref、Copy以及Pprint這些數(shù)據(jù)結(jié)構(gòu)的用法,需要的朋友可以參考下2015-03-03torch.optim優(yōu)化算法理解之optim.Adam()解讀
這篇文章主要介紹了torch.optim優(yōu)化算法理解之optim.Adam()解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11