基于OpenCV的圖像翻轉(zhuǎn)和鏡像
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時間送達(dá)
本期,我們將解釋如何在Python中實(shí)現(xiàn)圖像的鏡像或翻轉(zhuǎn)。大家只需要了解各種矩陣運(yùn)算和矩陣操作背后的基本數(shù)學(xué)即可。
NumPy —用于矩陣運(yùn)算并對其進(jìn)行處理。
OpenCV —用于讀取圖像并將其轉(zhuǎn)換為2D數(shù)組(矩陣)。
Matplotlib —用于將矩陣?yán)L制為圖像。

對于這個小型項(xiàng)目,我使用了著名的Lena圖像,該圖像主要用于測試計算機(jī)視覺模型。確保下載此映像并將其保存在當(dāng)前工作目錄中。
import cv2import numpy as npfrom matplotlib import pyplot as plt
首先,我們使用imread()模塊中的方法讀取圖像文件cv2。為此,我們只需要導(dǎo)入包并使用它即可。因此,通過這樣做,我們獲得了矩陣形式的圖像。默認(rèn)情況下,imread()該方法讀取的圖像BGR(Blue,Green,Red)格式。要讀取的圖像轉(zhuǎn)換為常規(guī)格式,即,RGB(Red,Green,Blue),我們使用cvtColor()來自同一模塊的方法cv2。
def read_this(image_file, gray_scale=False):image_src = cv2.imread(image_file)if gray_scale:image_rgb = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)else:image_rgb = cv2.cvtColor(image_src, cv2.COLOR_BGR2RGB)return image_rgb
上面的函數(shù)從傳遞的圖像文件返回圖像矩陣。如果我們要獲取圖像矩陣或格式,它由常規(guī)if和else條件組成。
鏡像圖像
要基本鏡像圖像,我們需要從左到右逐行反轉(zhuǎn)矩陣。讓我們考慮一個matrix A。
>>> A = [[],[],[]]
如果我們要鏡像此矩陣(逐行),則它將是-
> import numpy as np> mirror_ = np.fliplr(A)> mirror_[[1, 1, 4],[0, 8, 2],[1, 8, 3]]
我們也可以在不使用NumPy模塊的情況下執(zhí)行此操作。如果是這樣,我們可以使用循環(huán)并反轉(zhuǎn)每一行。如果在圖像矩陣上執(zhí)行相同的操作將花費(fèi)一些時間,因?yàn)樗鼈兪欠浅4蟮木仃嚕⑶椅覀儾幌M覀兊拇a執(zhí)行得非常慢。
def mirror_this(image_file, gray_scale=False, with_plot=False):image_rgb = read_this(image_file=image_file, gray_scale=gray_scale)image_mirror = np.fliplr(image_rgb)if with_plot:fig = plt.figure(figsize=(10, 20))ax1 = fig.add_subplot(2, 2, 1)ax1.axis("off")ax1.title.set_text('Original')ax2 = fig.add_subplot(2, 2, 2)ax2.axis("off")ax2.title.set_text("Mirrored")if not gray_scale:ax1.imshow(image_rgb)ax2.imshow(image_mirror)else:ax1.imshow(image_rgb, cmap='gray')ax2.imshow(image_mirror, cmap='gray')return Truereturn image_mirror
上面的函數(shù)返回一個圖像矩陣,該矩陣從左向右逐行反轉(zhuǎn)或翻轉(zhuǎn)。
讓我們繪制相同的內(nèi)容-
mirror_this(image_file="lena_original.png", with_plot=True)
mirror_this(image_file="lena_original.png", gray_scale=True, with_plot=True)
翻轉(zhuǎn)圖像
要基本翻轉(zhuǎn)圖像,我們需要將矩陣從上到下逐列反轉(zhuǎn)。讓我們考慮一個matrix B。
>>> B = [[],[],[]]
如果我們要翻轉(zhuǎn)此矩陣(按列),則它將是-
> import numpy as np> flip_= np.flipud(B)> flip_[[3, 8, 1],[2, 8, 0],[4, 1, 1]]
我們NumPy用于翻轉(zhuǎn)矩陣以保持代碼的牢固性。
def flip_this(image_file, gray_scale=False, with_plot=False):image_rgb = read_this(image_file=image_file, gray_scale=gray_scale)image_flip = np.flipud(image_rgb)if with_plot:fig = plt.figure(figsize=(10, 20))ax1 = fig.add_subplot(2, 2, 1)ax1.axis("off")ax1.title.set_text('Original')ax2 = fig.add_subplot(2, 2, 2)ax2.axis("off")ax2.title.set_text("Flipped")if not gray_scale:ax1.imshow(image_rgb)ax2.imshow(image_flip)else:ax1.imshow(image_rgb, cmap='gray')ax2.imshow(image_flip, cmap='gray')return Truereturn image_flip
上面的函數(shù)返回一個圖像矩陣,該矩陣從上向下向下按列反轉(zhuǎn)或翻轉(zhuǎn)。
讓我們繪制相同的內(nèi)容-
flip_this(image_file='lena_original.png', with_plot=True)
flip_this(image_file='lena_original.png', gray_scale=True, with_plot=True)
class ImageOpsFromScratch(object):def __init__(self, image_file):self.image_file = image_filedef read_this(self, gray_scale=False):image_src = cv2.imread(self.image_file)if gray_scale:image_rgb = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)else:image_rgb = cv2.cvtColor(image_src, cv2.COLOR_BGR2RGB)return image_rgbdef mirror_this(self, with_plot=True, gray_scale=False):image_rgb = self.read_this(gray_scale=gray_scale)image_mirror = np.fliplr(image_rgb)if with_plot:self.plot_it(orig_matrix=image_rgb, trans_matrix=image_mirror, head_text='Mirrored', gray_scale=gray_scale)return Nonereturn image_mirrordef flip_this(self, with_plot=True, gray_scale=False):image_rgb = self.read_this(gray_scale=gray_scale)image_flip = np.flipud(image_rgb)if with_plot:self.plot_it(orig_matrix=image_rgb, trans_matrix=image_flip, head_text='Flipped', gray_scale=gray_scale)return Nonereturn image_flipdef plot_it(self, orig_matrix, trans_matrix, head_text, gray_scale=False):fig = plt.figure(figsize=(10, 20))ax1 = fig.add_subplot(2, 2, 1)ax1.axis("off")ax1.title.set_text('Original')ax2 = fig.add_subplot(2, 2, 2)ax2.axis("off")ax2.title.set_text(head_text)if not gray_scale:ax1.imshow(orig_matrix)ax2.imshow(trans_matrix)else:ax1.imshow(orig_matrix, cmap='gray')ax2.imshow(trans_matrix, cmap='gray')return True
imo = ImageOpsFromScratch(image_file='lena_original.png')### Mirroring ###imo.mirror_this()imo.mirror_this(gray_scale=True)### Flipping ###imo.flip_this()imo.flip_this(gray_scale=True)
將顯示以上圖像結(jié)果。現(xiàn)在,所有內(nèi)容都已排序,我們可以創(chuàng)建其他圖像操作,例如equalize(),solarize()等等。
交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


