如opencv開(kāi)發(fā)前的準(zhǔn)備工作中所說(shuō),此系列文章是在學(xué)習(xí)Practical Python and OpenCV(點(diǎn)擊下載)這本書(shū)的一些記錄,發(fā)出來(lái)的文章跳過(guò)了第三章對(duì)RGB,以及numpy簡(jiǎn)單操作等介紹,請(qǐng)大家下載原書(shū)查看,在原書(shū)中對(duì)一下段落已進(jìn)行翻譯注釋。文章系列完整展示代碼點(diǎn)擊下載
import numpy as np
import cv2
import argparse
import imutils
ap = argparse.ArgumentParser()
ap.add_argument("-i","--image", required =True,
help ="Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Original", image)
cv2.waitKey(0)
M = np.float32([[1,0,25],[0,1,50]])
#定義我們的平移矩陣M
#矩陣M被定義為一個(gè)浮點(diǎn)數(shù)組 - 這很重要,因?yàn)镺penCV期望這個(gè)矩陣是浮點(diǎn)類型的。
#矩陣的第一行是[1,0,tx],其中tx是像素的數(shù)量,我們將左右移動(dòng)圖像。
#tx的負(fù)值會(huì)將圖像左移,正值會(huì)將圖像向右移
#我們將矩陣的第二行定義為[0,1,ty],其中ty是我們將向上或向下移動(dòng)圖像的像素?cái)?shù)量。
#ty的負(fù)值會(huì)使圖像向上移動(dòng),正值會(huì)使圖像向下移動(dòng)。
shifted =cv2.warpAffine(image ,M ,(image.shape[1], image.shape[0]))
#warpAffine第一個(gè)參數(shù)是我們想要移動(dòng)的圖像,第二個(gè)參數(shù)是我們的平移矩陣M.最后,我們手動(dòng)提供圖像的尺寸(寬度和高度)作為第三個(gè)參數(shù)
cv2.imshow("Shifted Up and Left",shifted)
M = np.float32([[1,0,-50],[0,1,-90]])
shifted =cv2.warpAffine(image ,M ,(image.shape[1], image.shape[0]))
cv2.imshow("Shifted Up and Left",shifted)
cv2.waitKey(0)
以上多次使用warpAffine重復(fù)性很高而且 使用起來(lái)不方便,我們可以定義一個(gè)叫imutils.py的模塊封裝這個(gè)方法如下:
import numpy as np
import cv2
def? translate(image, x, y):
???? M = np.float32([[1,0, x], [0,1, y]])
??? shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
???? return shifted
再實(shí)現(xiàn)上面平移的動(dòng)作:
shifted =imutils.translate(image,0,100)
cv2.imshow("Shifted Up and Left",shifted)
Rotation 旋轉(zhuǎn)一個(gè)角度q的圖像。
import numpy as np
import cv2
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-i","--image",required =True,help ="Path to the image")
args =vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Original",image)
(h,w) = image.shape[:2]
center = (w//2,h//2)
M = cv2.getRotationMatrix2D(center,45,1.0)
#cv2.getRotationMatrix2D(center, degrees , scale)
#center為需要圍繞旋轉(zhuǎn)的點(diǎn),當(dāng)我們旋轉(zhuǎn)圖像時(shí),我們需要指定我們要旋轉(zhuǎn)的點(diǎn)。
#在大多數(shù)情況下,你會(huì)想要圍繞圖像的中心旋轉(zhuǎn);然而,
#OpenCV允許你指定你想旋轉(zhuǎn)的任意點(diǎn)
# degrees 旋轉(zhuǎn)的角度
# scale 比例 這里你可以指定一個(gè)浮點(diǎn)值,其中1.0意味著使用相同的圖像轉(zhuǎn)換。但是,如果您指定的值為2.0,則圖像的大小將加倍。類似地,0.5的值將圖像的大小減半。
#就像我們定義矩陣來(lái)翻譯圖像一樣,我們也定義了一個(gè)矩陣來(lái)旋轉(zhuǎn)圖像。我們只需要調(diào)用cv2.getRotationMatrix2D方法,而不是使用NumPy手工構(gòu)造矩陣
rotated = cv2.warpAffine(image, M,(w,h))
cv2.imshow("Rotated by 45 Degrees", rotated)
M = cv2.getRotationMatrix2D(center,-90,1.0)
rotated = cv2.warpAffine(image, M ,(w,h))
cv2.imshow("Rotated by -90 Degrees",rotated)
rotated = imutils.rotate(image,60,None,0.5)
cv2.imshow("Rotated by imutils",rotated)
cv2.waitKey(0)
封裝rotate方法
工具類imutils.py
def rotate(image, angle ,center= None,scale =1.0):
??? (h,w)= image.shape[:2]
?? ifcenterisNone:
??? center =(w /2,h/2)
? ? M = cv2.getRotationMatrix2D(center,angle,scale)
? ? rotated = cv2.warpAffine(image, M ,(w,h))
??? return rotated
調(diào)用方式:
rotated = imutils.rotate(image,60,None,0.5)
import numpy as np
import cv2
import argparse
import imutils
ap = argparse.ArgumentParser()
ap.add_argument("-i","--image",required =True,help ="Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Original",image)
r =150.0/image.shape[1]
#定義新圖片的寬度為150,為了計(jì)算新圖片的高度,計(jì)算出新圖片寬度和當(dāng)前圖片寬度的比例。
dim = (150,int(image.shape[0]*r))
#新圖片的寬高
resized = cv2.resize(image , dim, interpolation = cv2.INTER_AREA)
#cv2.resize(image,dim,interpolation)?
#image 需要調(diào)整的圖片? ? dim 新圖片的尺寸
#最后一個(gè)參數(shù)是我們的插值方法,它是在幕后處理實(shí)際圖像大小調(diào)整的算法
#cv2.INTER_AREA,cv2.INTER_LINEAR,cv2.INTER_CUBIC,cv2.INTER_NEAREST
# interpolation 可選參數(shù)
# INTER_NEAREST - a nearest-neighbor interpolation
# INTER_LINEAR - a bilinear interpolation (used by default)
# INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
# INTER_CUBIC - a bicubic interpolation over 4x4 pixel neighborhood
# INTER_LANCZOS4 - a Lanczos interpolation over 8x8 pixel neighborhood
NTER_NEAREST - 最近鄰居插值
INTER_LINEAR - 雙線性插值(默認(rèn)使用)
INTER_AREA - 使用像素區(qū)域關(guān)系重采樣。這可能是圖像抽取的首選方法,因?yàn)樗梢援a(chǎn)生無(wú)莫爾效應(yīng)的結(jié)果。但是當(dāng)圖像放大時(shí),它與INTER_NEAREST方法類似。
INTER_CUBIC -4x4像素鄰域上的雙三次插值
INTER_LANCZOS4 -8x8像素鄰域上的Lanczos插值
cv2.imshow("resized(width)",resized)
cv2.waitKey(0)
我們可以在x或y軸周圍翻轉(zhuǎn)圖像,甚至可以翻轉(zhuǎn)圖像(We can flip an image around either the x or y axis, or even both.)
import argparse
import cv2
ap = argparse.ArgumentParser()
ap.add_argument("-i","--image",required =True,help ="Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Original",image)
flipped = cv2.flip(image,1)
cv2.imshow("Flipped Horizontally",flipped)
#使用1的翻轉(zhuǎn)代碼值表示我們將水平地圍繞y軸翻轉(zhuǎn)圖像。
flipped = cv2.flip(image,0)
# 指定一個(gè)0的翻轉(zhuǎn)代碼表示我們想要垂直翻轉(zhuǎn)圖像,圍繞X軸
cv2.imshow("Flipped Vertically",flipped)
flipped = cv2.flip(image,-1)
# 使用負(fù)向翻轉(zhuǎn)代碼將圖像翻轉(zhuǎn)兩個(gè)軸。
cv2.imshow("Flipped Horizontally&Vertically",flipped)
cv2.waitKey(0)
圖片的裁剪使用NumPy數(shù)組切片來(lái)完成圖像裁剪
import numpy as np
import argparse
import cv2
ap = argparse.ArgumentParser()
ap.add_argument("-i","--image",required =True, help="Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Original",image)
#NumPy數(shù)組中高度在前面,寬度在后面
cropped = image[30:220,10:335]
#所以我們需要截取的區(qū)域值定義需要按照numpy的格式,如上[starty:endy,startx:endx]
# 1.Start y: The starting y coordinate. In this case, we
# start at y = 30.
# 2. End y: The ending y coordinate. We will end our crop
# at y = 220.
# 3. Start x: The starting x coordinate of the slice. We start
# the crop at x = 10.
# 4. End x: The ending x-axis coordinate of the slice. Our
# slice ends at x = 335.
cv2.imshow("update",cropped)
cv2.waitKey(0)
凡事往簡(jiǎn)單處想,往認(rèn)真處行。
更多文章請(qǐng)關(guān)注我的博客:https://harveyyeung.github.io