[OpenCV基礎][Python]遮罩,旋轉,輪廓應用濾除斑點

2024/01/06閱讀時間約 14 分鐘

[影像處理_OpenCV Python]使用Python撰寫影像處理功能,圖片遮罩或濾除掉不要的地方,旋轉圖片

前言

以下範例將呈現影像處理三種不同的應用:

遮罩的實現

利用cv2.add用法來實現mask,黑色的像素0則會遮蔽掉呈現黑色,白色像素255則會透明的方式顯現出原圖的樣子

濾除不要的斑點(白點)

利用 cv2.findContours用法來實現mask,黑色的像素0則會遮蔽掉呈現黑色,白色像素255則會透明的方式顯現出原圖的樣子

旋轉圖片

利用cv2.warpAffinecv2.getRotationMatrix2D實現圖片旋轉

結果圖

raw-image
raw-image
raw-image

程式碼範例及連結


程式範例說明

遮罩的實現

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()
  1. import cv2import numpy as npimport matplotlib.pyplot as plt:引入OpenCV、NumPy和Matplotlib庫,這些庫用於處理圖像和顯示結果。
  2. img1 = cv2.imread('./images.jpg'):讀取一張名為"images.jpg"的圖片,存儲在img1中。
  3. img2 = np.zeros((224, 224), dtype=np.uint8):創建一張大小為224x224的黑色圖片,存儲在img2中,後面將用於遮罩用。
  4. cv2.circle(img2, (112, 112), 70, 255, thickness=cv2.FILLED):在img2上畫一個白色的圓形,中心座標為(112, 112),半徑為70,顏色為255全白色,並且使用cv2.FILLED參數填充整個圓形內部。
  5. img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY):將彩色圖片img1轉換為灰度圖,存儲在img1_gray中。
  6. result = cv2.add(img1_gray, img1_gray, mask=img2):利用cv2.add將兩張灰度圖相加,其中img2的白色部分將透明顯示原圖,黑色部分則被遮罩掉。
  7. result_colored = cv2.cvtColor(result, cv2.COLOR_BGR2RGB):將最終的結果轉換回彩色圖,以便在Matplotlib中顯示。
  8. img2 = cv2.cvtColor(img2, cv2.COLOR_GRAY2BGR):將img2轉換回彩色圖,以便在Matplotlib中顯示。
  9. Matplotlib的部分:使用plt.subplotplt.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()
  1. def rotate_image(image, angle)::定義了一個函數,用於旋轉圖片。接受一張圖片image和旋轉角度angle作為參數。
  2. center = tuple(np.array(image.shape[1::-1]) / 2):取得圖片的中心點坐標。
  3. rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0):使用cv2.getRotationMatrix2D來獲得旋轉矩陣,其中center是旋轉的中心點,angle是旋轉的角度,1.0是縮放因子。
  4. rotated_image = cv2.warpAffine(image, rotation_matrix, image.shape[1::-1], flags=cv2.INTER_LINEAR):使用cv2.warpAffine進行影像旋轉,flags=cv2.INTER_LINEAR表示使用線性插值。

謝謝大家觀看,若喜歡在麻煩動動小手給點愛心 感謝:)





48會員
81內容數
Python程式設計師,不是在學習就是在學習的路上
留言0
查看全部
發表第一個留言支持創作者!
從 Google News 追蹤更多 vocus 的最新精選內容