1.圖片的縮放
圖片是由許多基本的像素點組成的,一般來說彩色圖像中的像素點由三個數值組成,分別是藍色分量、紅色分量和綠色分量。
圖片縮放分為:
- 普通的縮放,即確定下縮放后的尺寸大小,再進行縮放。
- 等比例縮放,即確定一個比例系數,長寬都乘以一個相同的比例系數,實現等比例縮放。
一般來說,圖片的縮放方法有:
- 最近臨域插值
- 雙線性插值(默認情況)
- 像素關系重采樣
- 立方插值
下面簡單實現等比例縮放,用最近領域插值方法實現,測試代碼如下:
1 # encoding:utf-8 2 # 基本實現步驟: 3 # 1 load 讀取圖片 4 # 2 info 獲取圖片信息 5 # 3 resize 實現圖片縮放即改變圖片大小 6 # 4 check 展示操作后的圖像 7 import cv2 8 img = cv2.imread('image0.jpg', 1) 9 # 圖片的大小 10 imgInfo = img.shape 11 print(imgInfo) 12 height = imgInfo[0] 13 width = imgInfo[1] 14 mode = imgInfo[2] # 為3 表示一個像素點由三個數值組成 15 cv2.imshow('src', img) 16 # 1 放大 縮小 17 # 2 等比例縮放 寬高比不變即為等比例縮放 18 # 等比例縮放 長寬乘以一個相同的系數 19 dstHeight = int(height*0.5) 20 dstWidth = int(width*0.5) 21 # 非等比例縮放 22 # dstHeight = 500 23 # dstWidth = 500 24 # 縮放方法:最近臨域插值 雙線性插值(默認情況) 像素關系重采樣 立方插值 25 dst = cv2.resize(img, (dstWidth, dstHeight)) 26 cv2.imshow('image', dst) 27 cv2.waitKey(0)
運行效果如下:(src為原始圖像,dst為目標圖像即縮放后的圖像)
原始圖像:
縮放后的圖像:
下面簡單的說下最近臨域插值的雙線性插值(默認情況)的原理:
1 # 原圖像src 10*20 目標圖像dst 5*10 2 # src-->dst 3 # (2,4)-->(1,2) 4 # 計算公式 dst x 1 -> src x 2 newX 5 # newX=x*(src的行/dst的行) newX=1*(10/5)=2 6 # newY=y*(src的列/目標的列) newY=2*(20/10)=4 7 # 12.3 = 12 最近領域插值法 取最近的整數 8 # 9 # 雙線性插值法 10 # A1=20% 上+ 80% 下 A2 11 # B1=30% 左+ 70% 右 B2 12 # 1 最終點 = A1 30% + A2 70% 13 # 2 最終點 = B1 20% + B2 80%
簡單的實現下最近領域插值算法,測試代碼如下:
1 # 最近臨域插值算法代碼實現 2 import cv2 3 import numpy as np 4 img = cv2.imread('image0.jpg', 1) 5 imgInfo = img.shape 6 height = imgInfo[0] 7 width = imgInfo[1] 8 dstHeight = int(height/3) 9 dstWidth = int(width/2) 10 dstImage = np.zeros((dstHeight, dstWidth, 3), np.uint8) # 0-255 創建一個空白模版 11 for i in range(0, dstHeight): # 行 12 for j in range(0, dstWidth): # 列 13 iNew = int(i*(height*1.0/dstHeight)) 14 jNew = int(j*(width*1.0/dstWidth)) 15 dstImage[i, j] = img[iNew, jNew] 16 cv2.imshow('dst', dstImage) 17 cv2.waitKey(0)
運行結果如下:(即展示縮放后的圖像)
圖像的縮放再測試,代碼如下:
1 # 圖片縮放 2 import cv2 3 import numpy as np 4 img = cv2.imread('image0.jpg', 1) 5 cv2.imshow('src', img) 6 imgInfo = img.shape 7 height = imgInfo[0] 8 width = imgInfo[1] 9 matScale = np.float32([[0.5, 0, 0], [0, 0.5, 0]]) 10 dst = cv2.warpAffine(img,matScale,(int(width/2),int(height/2))) 11 cv2.imshow('dst',dst) 12 cv2.waitKey(0)
運行結果如下:(src為初始圖像,dst為目標圖像)
src初始圖像:
dst縮放后的圖像:
2.圖片的剪切
圖片剪切的大致原理,按照我的理解就是:確定兩個點,連接兩個的線段即為剪切矩陣的對角線,通過這兩個的坐標,就可以確定需要剪切的矩陣的方位以及矩陣大小。
更通俗一點的理解就是,你在用QQ截圖的時候,總是先點一個起始點,最后再點一個終止點,最后形成一個矩陣,最后再輸出這個矩陣中所有的像素值,即為剪切后的圖片。
圖片的剪切,測試代碼如下:
1 # 實現圖片的剪切 2 import cv2 3 img = cv2.imread('image0.jpg', 1) 4 cv2.imshow('src', img) 5 imgInfo = img.shape 6 # dst = img[100:500, 200:500] 7 dst = img[100:400, 100:500] # 前面是縱向的范圍 后面的是橫向的范圍 8 cv2.imshow('image', dst) 9 cv2.waitKey(0)
運行結果如下:(src為原始圖像,image為目標圖像)
src原始圖像:
image剪切后的圖像:(剪了一朵大發發)
3.圖片的移位
通過api調用實現圖片的移位,測試代碼如下:
1 # 通過api調用實現圖片的移位 2 import cv2 3 import numpy as np 4 img = cv2.imread('image0.jpg', 1) 5 imgInfo = img.shape 6 height = imgInfo[0] 7 width = imgInfo[1] 8 img = cv2.resize(img,(int(height*0.5),int(width*0.5))) # 原始圖像長寬縮小一半 9 cv2.imshow('src', img) 10 # 移位矩陣 11 matShift = np.float32([[1,0,50],[0,1,100]]) # 第一個移位矩陣 12 matShift2 = np.float32([[1,0,200],[0,1,100]]) # 第二個移位矩陣 13 # 目標矩陣 14 dst = cv2.warpAffine(img,matShift,(height,width-200)) # 第一個目標矩陣 15 dst2 = cv2.warpAffine(img,matShift2,(height,width-200)) # 第二個目標矩陣 16 # 展示兩個目標圖像 17 cv2.imshow('dst',dst) 18 cv2.imshow('dst2',dst2) 19 cv2.waitKey(0)
運行結果如下:(src為測試圖像,dst為第一個移位后的圖像,dst2為第二個移位后的圖像)
src測試圖像:
dst第一個移位圖像:
dst2第二個移位圖像:
自行實現圖片向右移動100個像素,測試代碼如下:
1 # 自行實現圖片向右移動100個像素 2 import cv2 3 import numpy as np 4 img = cv2.imread('image0.jpg', 1) 5 img = cv2.resize(img,(int(img.shape[0]*0.5),int(img.shape[1]*0.5))) 6 cv2.imshow('src',img) 7 imgInfo = img.shape 8 height = imgInfo[0] 9 width = imgInfo[1] 10 dst = np.zeros(img.shape,np.uint8) 11 for i in range(0,height): 12 for j in range(0,width-100): 13 dst[i,j+100]=img[i,j] 14 cv2.imshow('image',dst) 15 cv2.waitKey(0)
運行結果如下:(src為原始圖像,image為移位后的圖像)
src原始圖像:
image移位后的圖像:
4.圖片鏡像
圖像鏡像的實現步驟是:
- 先創建一個最夠大的畫板,能夠“裝得下”鏡像化之后的圖像
- 然后再將該圖像分別從前向后、從后向前繪制
- 最后繪制中心分割線
測試代碼如下:
1 import cv2 2 import numpy as np 3 img = cv2.imread('image0.jpg', 1) 4 img = cv2.resize(img,(int(img.shape[0]*0.5),int(img.shape[1]*0.3))) 5 cv2.imshow('src', img) 6 imgInfo = img.shape 7 height = imgInfo[0] 8 width = imgInfo[1] 9 deep = imgInfo[2] 10 newImgInfo = (height*2, width, deep) 11 dst = np.zeros(newImgInfo, np.uint8) 12 for i in range(0, height): 13 for j in range(0, width): 14 dst[i, j] = img[i, j] 15 # x y = 2*j - y- 1 16 dst[height*2-i-1, j] = img[i, j] 17 for i in range(0, width): 18 dst[height, i] = (0, 0, 255) 19 cv2.imshow('image', dst) 20 cv2.waitKey(0)
運行結果如下:(src為初始圖像,image為鏡像后的圖像)
src初始圖像:
image鏡像后的圖像:
5.圖片的放射變換
放射變換融合了如下幾點:
- 位移
- 旋轉
- 縮放
測試代碼如下:
1 # 仿射變換:位移 旋轉 縮放 2 import cv2 3 import numpy as np 4 img = cv2.imread('image0.jpg', 1) 5 cv2.imshow('src', img) 6 imgInfo = img.shape 7 height = imgInfo[0] 8 width = imgInfo[1] 9 # src 3->dst 3 (左上角 左下角 右上角) 10 matSrc = np.float32([[0,0],[0,height-1],[width-1,0]]) 11 matDst = np.float32([[50,50],[300,height-200],[width-300,100]]) 12 # 組合 13 matAffine = cv2.getAffineTransform(matSrc,matDst) 14 dst = cv2.warpAffine(img,matAffine,(width,height)) 15 cv2.imshow('dst',dst) 16 cv2.waitKey(0)
運行結果如下:(src為初始圖像,dst為目標圖像)
src初始圖像:
dst目標圖像:
6.圖片的旋轉
調用api實現圖片的旋轉,測試代碼如下:(主要有三個參數,旋轉中心的坐標、旋轉角度以及縮放系數(至於為什么有縮放系數,因為旋轉的時候可能會觸碰到圖像矩陣框的邊緣,所以需要縮放處理))
1 # 圖片旋轉 2 import cv2 3 import numpy as np 4 img = cv2.imread('image0.jpg', 1) 5 img = cv2.resize(img,(int(img.shape[0]*0.5),int(img.shape[1]*0.5))) 6 cv2.imshow('src', img) 7 imgInfo = img.shape 8 height = imgInfo[0] 9 width = imgInfo[1] 10 # 得到旋轉矩陣 center angle sc 中心點 角度 縮放系數 11 matRotate = cv2.getRotationMatrix2D((height*0.5,width*0.5),45,0.7) 12 dst = cv2.warpAffine(img,matRotate,(height,int(width*1.5))) 13 cv2.imshow('image',dst) 14 cv2.waitKey(0)
運行效果如下:(src為初始圖像,image為目標圖像)
src初始圖像:
image目標圖像:
暫時先記下這么多,還有的話再更新。。。