【計算機視覺—python 】 圖像處理入門教程 —— 圖像屬性、像素編輯、創(chuàng)建與復制、裁剪與拼接【 openCV 學習筆記 005 to 010 and 255】
1、圖像屬性
OpenCV中讀取圖像文件后的數據結構符合Numpy的ndarray多維數組結構,因此 ndarray 數組的屬性和操作方法可用于圖像處理的一些操作。數據結構如下圖所示:
- img.ndim:查看代表圖像的維度。彩色圖像的維數為3,灰度圖像的維度為2。
- img.shape:查看圖像的形狀,代表矩陣的行數(高度)、列數(寬度)、通道數。
- img.size:查看圖像數組元素總數,灰度圖像的數組元素總數為像素的數量,彩色圖像的數組元素總數為像素數量與通道數的乘積
# 打印圖像的參數
import cv2
imgFile = r"test.jpg" # 圖片和代碼 我放一個目錄下了
img1 = cv2.imread(imgFile) # 默認是 flags=1 三通道彩圖
img2 = cv2.imread(imgFile,0) # 讀取為灰度圖像
cv2.imwrite("testGray.jpg",img2) # 保存一下 留著看詳細信息
# cv2.imshow("test1",img1) #自己測試看一下
# cv2.imshow("test2",img2) #自己測試看一下
# cv2.waitKey(0)
# 打印輸出img1和img2的信息 圖像的維數(ndim), 形狀(shape), 元素總數(size), 元素類型(dtype)
print("ndim of img1(BGR): {}, img2(Gray): {}".format(img1.ndim, img2.ndim)) # 打印兩個圖像的 維度
print("shape of img1(BGR): {}, img2(Gray): {}".format(img1.shape, img2.shape)) # 打印兩個圖像的 形狀(高,寬,通道)
print("Size of img1(BGR): {}, img2(Gray): {}".format(img1.size, img2.size)) # 打印兩個圖像的 元素總數
print("dtype of img1(BGR): {}, img2(Gray): {}".format(img1.dtype, img2.dtype)) # 打印兩個圖像的 元素類型
# 上塊代碼的輸出結果
ndim of img1(BGR): 3, img2(Gray): 2
shape of img1(BGR): (676, 716, 3), img2(Gray): (676, 716)
Size of img1(BGR): 1452048, img2(Gray): 484016
dtype of img1(BGR): uint8, img2(Gray): uint8
在文件夾中右鍵圖片—>屬性—>詳細屬性中,查看兩個圖片信息,位深度除8(好像是因為8byte)為通道數。(3通道藍綠紅,單通道黑白)
2、像素編輯
像素是構成數字圖像的基本單位,像素處理是圖像處理的基本操作。
通過直接改變圖像數組矩陣的值來直接改變圖像。
# 像素編輯的一些操作
import cv2
img1 = cv2.imread("test.jpg") # 不用變量了 直接讀路徑 讀取默認彩圖
x, y = 500,500 # 根據橫縱左邊直接選取像素位置(x,y)
# 直接訪問數組元素,打印獲取像素值(BGR格式)
print("x={},y={}\n img[x,y] = {}".format(x,y,img1[x,y]))
# 遍歷 分別打印三個通道中 每個通道的數值
print(" img[{},{},ch]:".format(x,y),end="")
for i in range(3):
print(img1[x,y,i] , end= " ")
# 遍歷 通過 img1.item() 分別打印三個通道中 每個通道的數值
print("\n img.item({},{},ch):".format(x,y),end="")
for i in range(3):
print(img1.item(x,y,i),end=" ")
# 通過 img1.itemset() 修改像素通道中的數值 0通道的數值改成255
ch, newValue = 0, 255
print("\n orignal img[x,y] = {}".format(img1[x,y]))
img1.itemset((x,y,ch),newValue)
print(" updated img[x,y] = {}".for mat(img1[x,y]))
# 運行結果
x=500,y=500
img[x,y] = [26 23 18]
img[500,500,ch]:26 23 18
img.item(500,500,ch):26 23 18
orignal img[x,y] = [26 23 18]
updated img[x,y] = [255 23 18]
3、圖像的創(chuàng)建與復制
創(chuàng)建
根據圖像數據結構符合Numpy的ndarray多維數組結構的特性,可以使用Numpy中 np.zeros()
等方法創(chuàng)建指定大小、類型的圖像對象,也可以使用 np.zeros_like()
等方法創(chuàng)建與已有圖像大小、類型相同的新圖像。
# 圖像創(chuàng)建的一些操作
import cv2
import numpy as np
# 通過寬高值創(chuàng)建
height, width, channels = 400, 300, 3 # 行/高度, 列/寬度, 通道數
imgEmpty = np.empty((height,width,channels),np.uint8) # 創(chuàng)建空數組
imgBlack = np.zeros((height,width,channels),np.uint8) # 創(chuàng)建黑色圖像 RGB=0
imgWhite = np.ones((height, width, channels), np.uint8) * 255 # 創(chuàng)建白色圖像 RGB=255
cv2.imshow("imgBlack",imgBlack) # 顯示出來看下
cv2.imshow("imgWhite",imgWhite) # 顯示出來看下
cv2.waitKey(0)
# 創(chuàng)建相同形狀的多維數組
img1 = cv2.imread("test.jpg") # 取彩色圖像(BGR)
imgBlackLike = np.zeros_like(img1) # 創(chuàng)建與 img1 相同形狀大小的黑色圖像
imgWhiteLike = np.ones_like(img1) * 255 # 創(chuàng)建與 img1 相同形狀大小的白色圖像
cv2.imshow("imgBlackLike",imgBlackLike) # 顯示出來看下
cv2.imshow("imgWhiteLike",imgWhiteLike) # 顯示出來看下
cv2.waitKey(0)
# 創(chuàng)建彩色隨機圖像 RGB=random
import os # 導入庫 沒配環(huán)境的自己查一下
randomByteArray = bytearray(os.urandom(height * width * channels)) #在范圍: 0 <= x < 256里(bytearray函數),生成隨機字節(jié)串(os.urandom)
flatNumpyArray = np.array(randomByteArray) # 將隨機字符串 轉換成 Numpy中的 ndarray數據結構
imgRGBRand = flatNumpyArray.reshape(height, width, channels) # 將矩陣轉換為特定的行、列和通道的三維矩陣
cv2.imshow("imgRGBRand",imgRGBRand) # 顯示出來看下
cv2.waitKey(0)
# 創(chuàng)建灰度圖像 Gray=random
imgGrayWhite = np.ones((height,width),np.uint8) * 255 # 創(chuàng)建白色圖像
imgGrayBlack = np.zeros((height,width),np.uint8) # 創(chuàng)建黑色圖像
imgGrayEye = np.eye(width) # 創(chuàng)建對角線為 1的單位矩陣
randomByteArray = bytearray(os.urandom(height * width )) # 注意灰度通道為 1 不用 *channel
flatNumpyArray = np.array(randomByteArray)
imgGrayRand = flatNumpyArray.reshape(height,width) # 將矩陣轉換為特定的行、列二維矩陣
cv2.imshow("imgGrayRand",imgGrayRand) # 顯示出來看下
cv2.waitKey(0)
這里我只展示 隨機生成的彩圖和灰圖,樣例建議動手操作下。
復制
也是根據圖像數據結構特性,使用 Numpy 的 np.copy() 函數可以進行圖像的復制,注意:不能通過直接賦值進行圖像的復制。
# 圖像復制 直接賦值和copy的區(qū)別
import cv2
img1 = cv2.imread("test.jpg") # 讀取圖像
img2 = img1.copy() # 用 copy()函數賦值
print("用img2=img1.copy(),img2是img1嗎?",img1 is img2) # 打印確認img1和 img2是一個嗎
# 更改圖像的一塊作為標記
for col in range(100):
for row in range(100):
img2[col, row, :] = 0
img3 = cv2.imread("test.jpg")# 讀取圖像
img4 = img3 # 用 = 函數賦值
print("用img4=img3, img3是img4嗎?", img4 is img3) # 打印確認img3和 img4是一個嗎
# 更改圖像的一塊作為標記
for col in range(100):
for row in range(100):
img4[col,row,:] = 0
# 打印圖像看結果
cv2.imshow("Demo1",img1)
cv2.imshow("Demo2",img2)
cv2.imshow("Demo3",img3)
cv2.imshow("Demo4",img4)
cv2.waitKey(0)
根據圖片顯示結果發(fā)現(xiàn) img4=img3 直接賦值,改變 img4 的數值后 img3 的數值也被改變了;img2 = img1.copy(),改變 img2 的數值后 img1 并未發(fā)生改變。并且根據打印結果可以看到:
用img2=img1.copy(),img2是img1嗎? False
用img4=img3, img3是img4嗎? True
4、圖像的裁剪
可以用切邊直接對圖像進行裁剪,也可以用.copy()函數獲取拷貝副本。
# 圖像裁剪基礎操作
import cv2
img1 = cv2.imread("test.jpg") # 讀取圖像
xmin, ymin, w, h = 180, 190, 400, 300 # 圖像左上點為(0,0) (xmin,ymin)為框的左上角 w為向右的寬度 h為向下的高度
imgCrop = img1[ymin:ymin+h, xmin:xmin+w].copy() # 切片獲得裁剪后保留的圖像區(qū)域
cv2.imshow("imgCrop",imgCrop)
cv2.waitKey(0)
# cv2.selectROI() 可以通過鼠標選擇感興趣的矩形區(qū)域(ROI) 鼠標截圖
xmin, ymin, w, h = cv2.selectROI(img1,showCrosshair=True,fromCenter=False) # 返回的是一個元組[min_x,min_y,w,h] showCrosshair是否在矩形框里畫十字線 fromCenter是否是從矩形框的中心開始畫
imgROI = img1[ymin:ymin+h, xmin:xmin+w].copy()
cv2.imshow("ROI",imgROI)
cv2.waitKey(0)
4、圖像的拼接
用 Numpy 的數組堆疊方法可以進行圖像的拼接:
np.hstack() 按水平方向(列順序)拼接 2個或多個圖像,np.vstack() 按**垂直方向(行順序)拼接 2個或多個圖像,圖像的寬度(數組的列)必須相同**。
# 圖像裁剪基礎操作
import cv2
import numpy as np
img1 = cv2.imread("test.jpg") # 讀取圖像1
img2 = cv2.imread("testGray.jpg") # 讀取圖像2
img1 = cv2.resize(img1,(400,400)) # 將圖像1改變尺寸為 400*400(w × h)
img2 = cv2.resize(img2,(300,400)) # 將圖像2改變尺寸為 300*400(w × h)
img3 = cv2.resize(img2,(400,300)) # 將圖像2改變尺寸為 300*400(w × h)
imgStackH = np.hstack((img1,img2)) # 圖像1和2 水平拼接
imgStackV = np.vstack((img1,img3)) # 圖像1和3 垂直拼接
# 打印輸出形狀屬性(高,寬,通道)
print("水平拼接:\n Shape of img1, img2 and imgStackH: ", img1.shape, img2.shape, imgStackH.shape)
print("垂直拼接:\n Shape of img1, img3 and imgStackV: ", img1.shape, img3.shape, imgStackV.shape)
cv2.imshow("DemoStackH", imgStackH) # 在窗口顯示圖像 imgStackH
cv2.imshow("DemoStackV", imgStackV) # 在窗口顯示圖像 imgStackV
cv2.waitKey(0) # 等待按鍵命令
輸出結果:文章來源:http://www.zghlxwxcb.cn/news/detail-804278.html
水平拼接:
Shape of img1, img2 and imgStackH: (400, 400, 3) (400, 300, 3) (400, 700, 3)
垂直拼接:
Shape of img1, img3 and imgStackV: (400, 400, 3) (300, 400, 3) (700, 400, 3)
OpenCV 也提供了2個或多個圖像水平拼接或垂直拼接的函數 cv.hconcat 與 cv.vconcat,具體操作如下:
# OpenCV 拼接 cv2.hconcat和 用法
import cv2
import numpy as np
img1 = cv2.imread("test.jpg") # 讀取圖像1
img2 = cv2.imread("testGray.jpg") # 讀取圖像2
# 水平拼接
imgH1 = cv2.resize(img1,(400,400)) # 將圖像1改變尺寸為 400*400 (w×h)
imgH2 = cv2.resize(img2,(300,400)) # 將圖像2改變尺寸為 300*400 (w×h)
imgH3 = imgH2.copy()
# imgStackH = np.hstack((imgH1, imgH2, imgH3)) # Numpy用法 高度相同圖像可以橫向水平拼接
imgStackH = cv2.hconcat((imgH1, imgH2, imgH3)) # OpenCV用法 高高度相同圖像可以橫向水平拼接
# 打印輸出形狀屬性(高,寬,通道)
print("水平拼接:\nShape of imgH1, imgH2 and imgStackH: ", imgH1.shape, imgH2.shape, imgStackH.shape)
cv2.imshow("DemoStackH", imgStackH) # 在窗口顯示圖像 imgStackH
cv2.waitKey(0)
# # 垂直拼接
imgV1 = cv2.resize(img1,(400,400)) # 將圖像1改變尺寸為 400*400 (w×h)
imgV2 = cv2.resize(img2,(400,300)) # 將圖像2改變尺寸為 400*300 (w×h)
# imgStackV = np.vstack(((imgV1, imgV2)) # Numpy用法 高度相同圖像可以垂直拼接
# imgStackV = cv2.vconcat((imgV1, imgV2)) # 寬度相同圖像可以縱向垂直拼接
imgV = (imgV1,imgV2) # 生成數組或元組
imgStackV = cv2.vconcat(imgV)
# 打印輸出形狀屬性(高,寬,通道)
print("垂直拼接:\n Shape of img1, img3 and imgStackV: ", imgV1.shape, imgV2.shape, imgStackV.shape)
cv2.imshow("DemoStackV", imgStackV) # 在窗口顯示圖像 imgStackV
cv2.waitKey(0) # 等待按鍵命令
文章來源地址http://www.zghlxwxcb.cn/news/detail-804278.html
聲明:本文是向博主「youcans_」OpenCV例程300篇學習的自用學習筆記
原文鏈接:【youcans@qq.com, youcans的OpenCV例程300篇, https://blog.csdn.net/youcans/category_11459626.html】
到了這里,關于【計算機視覺—python 】 圖像處理入門教程 —— 圖像屬性、像素編輯、創(chuàng)建與復制、裁剪與拼接【 openCV 學習筆記 005 to 010 and 255】的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!