以下範例將呈現影像處理三種不同的應用:
利用cv2.add
用法來實現mask,黑色的像素0則會遮蔽掉呈現黑色,白色像素255則會透明的方式顯現出原圖的樣子
利用 cv2.findContours
用法來實現mask,黑色的像素0則會遮蔽掉呈現黑色,白色像素255則會透明的方式顯現出原圖的樣子
利用cv2.warpAffine
及cv2.getRotationMatrix2D
實現圖片旋轉
import cv2
import numpy as np
import matplotlib.pyplot as plt
'''
遮罩的實現
利用cv2.add用法來實現mask,黑色的像素0則會遮蔽掉呈現黑色,白色像素255則會透明的方式顯現出原圖的樣子
'''
# 建立300*300的白色圖像
img1 = cv2.imread('./images.jpg')
img2 = np.zeros((224, 224), dtype=np.uint8)
# 在第二張圖像上繪製一個白色圓形
cv2.circle(img2, (112, 112), 70, 255, thickness=cv2.FILLED)
# 將利用遮罩的方式取出想要的畫面
# 將彩色圖片轉換為灰度圖
img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
# 將灰度圖作為遮罩,進行相加
result = cv2.add(img1_gray, img1_gray, mask = img2)
# 將結果轉換回彩色圖
result_colored = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
img2 = cv2.cvtColor(img2, cv2.COLOR_GRAY2BGR)
# 顯示原始圖片和結果
plt.subplot(1, 3, 1), plt.imshow(img1), plt.title('Image 1'), plt.axis('off')
plt.subplot(1, 3, 2), plt.imshow(img2), plt.title('Image 2'), plt.axis('off')
plt.subplot(1, 3, 3), plt.imshow(result_colored), plt.title('Result with Mask'), plt.axis('off')
plt.show()
import cv2
、import numpy as np
、import matplotlib.pyplot as plt
:引入OpenCV、NumPy和Matplotlib庫,這些庫用於處理圖像和顯示結果。img1 = cv2.imread('./images.jpg')
:讀取一張名為"images.jpg"的圖片,存儲在img1
中。img2 = np.zeros((224, 224), dtype=np.uint8)
:創建一張大小為224x224的黑色圖片,存儲在img2
中,後面將用於遮罩用。cv2.circle(img2, (112, 112), 70, 255, thickness=cv2.FILLED)
:在img2
上畫一個白色的圓形,中心座標為(112, 112),半徑為70,顏色為255全白色,並且使用cv2.FILLED
參數填充整個圓形內部。img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
:將彩色圖片img1
轉換為灰度圖,存儲在img1_gray
中。result = cv2.add(img1_gray, img1_gray, mask=img2)
:利用cv2.add
將兩張灰度圖相加,其中img2
的白色部分將透明顯示原圖,黑色部分則被遮罩掉。result_colored = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
:將最終的結果轉換回彩色圖,以便在Matplotlib中顯示。img2 = cv2.cvtColor(img2, cv2.COLOR_GRAY2BGR)
:將img2
轉換回彩色圖,以便在Matplotlib中顯示。plt.subplot
和plt.imshow
來顯示原始圖片、遮罩圖片和最終帶有遮罩效果的結果圖片。最後使用plt.show()
顯示整體結果。import cv2
import numpy as np
import matplotlib.pyplot as plt
'''
濾除不想要的斑點(白點)
cv2.findContours 主要用於找尋物體的輪廓,通常在二值圖像(黑白圖像)中找尋物體的邊界。黑白圖像中的白色區域視為物體,黑色區域視為背景,findContours 會找尋物體和背景之間的邊界
'''
def filter_contours_by_area(img:np.ndarray,min_area_threshold):
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 找到輪廓
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
#找出最大最小輪廓方便設定
max_contour = max(contours, key=cv2.contourArea)
max_area = cv2.contourArea(max_contour)
min_contour = min(contours, key=cv2.contourArea)
min_area = cv2.contourArea(min_contour)
print(f'max_area:{max_area}')
print(f'min_area:{min_area}')
# 過濾輪廓,將面積小於 min_area_threshold 的輪廓區域設為背景值(0)
for contour in contours:
area = cv2.contourArea(contour)
if area < min_area_threshold:
cv2.drawContours(img, [contour], -1, 0, thickness=cv2.FILLED) #將白點 轉換成黑色
return img
#導入圖片
img1 = cv2.imread('./particle.jpg')
print(f'img1:{img1.shape}')
min_area_threshold = 1000 #設定想濾除的面積
#呼叫filter_contours_by_area函數
result_img = filter_contours_by_area(img1,min_area_threshold)
#因opencv導入圖片為BGR,PLT顯示圖片需要轉換成RGB
result_colored = cv2.cvtColor(result_img, cv2.COLOR_GRAY2BGR)
result_colored = cv2.cvtColor(result_colored, cv2.COLOR_BGR2RGB)
# 顯示原始圖片和結果
plt.subplot(1, 2, 1), plt.imshow(img1), plt.title('Image 1'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(result_colored), plt.title('result_img'), plt.axis('off')
plt.show()
def filter_contours_by_area(img:np.ndarray, min_area_threshold):
:定義了一個函數,接受一張圖片img
和最小面積閾值min_area_threshold
作為參數。
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
:使用cv2.findContours
找到圖片中的所有輪廓。這個函數返回輪廓的列表contours
。
max_contour = max(contours, key=cv2.contourArea)
min_contour = min(contours, key=cv2.contourArea)
:找到面積最大和最小的輪廓。
print(f'max_area:{max_area}')
、print(f'min_area:{min_area}')
:印出最大和最小輪廓的面積,方便等下設定濾除面積的基準參考值。
for contour in contours:
:遍歷所有輪廓。
area = cv2.contourArea(contour)
:計算當前輪廓的面積。
if area < min_area_threshold:
:如果面積小於指定的最小面積閾值,則將此輪廓的區域設為背景值(0),即將白點轉換為黑色。
cv2.drawContours(img, [contour], -1, 0, thickness=cv2.FILLED)
result_img = filter_contours_by_area(img1, min_area_threshold)
:呼叫函數,將圖片img1
濾除面積小於min_area_threshold
的白點,得到result_img
。
result_colored = cv2.cvtColor(result_img, cv2.COLOR_GRAY2BGR)
result_colored = cv2.cvtColor(result_colored, cv2.COLOR_BGR2RGB)
將結果圖轉換為彩色圖,因為Matplotlib與OPENCV色域不同,OPENCV為BGR的關係。
import cv2
import numpy as np
import matplotlib.pyplot as plt
def rotate_image(image, angle):
# 取得影像中心點坐標
center = tuple(np.array(image.shape[1::-1]) / 2)
# 設定旋轉矩陣
rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
# 進行影像旋轉
rotated_image = cv2.warpAffine(image, rotation_matrix, image.shape[1::-1], flags=cv2.INTER_LINEAR)
return rotated_image
img1 = cv2.imread('./images.jpg')
result_img = rotate_image(img1,90)
#因opencv導入圖片為BGR,PLT顯示圖片需要轉換成RGB
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
result_colored = cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)
# 顯示原始圖片和結果
plt.subplot(1, 2, 1), plt.imshow(img1), plt.title('Image 1'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(result_colored), plt.title('result_img'), plt.axis('off')
plt.show()
def rotate_image(image, angle):
:定義了一個函數,用於旋轉圖片。接受一張圖片image
和旋轉角度angle
作為參數。center = tuple(np.array(image.shape[1::-1]) / 2)
:取得圖片的中心點坐標。rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
:使用cv2.getRotationMatrix2D
來獲得旋轉矩陣,其中center
是旋轉的中心點,angle
是旋轉的角度,1.0
是縮放因子。rotated_image = cv2.warpAffine(image, rotation_matrix, image.shape[1::-1], flags=cv2.INTER_LINEAR)
:使用cv2.warpAffine
進行影像旋轉,flags=cv2.INTER_LINEAR
表示使用線性插值。