Python實(shí)現(xiàn)圖片分割的多種方法總結(jié)
圖片分割是圖像處理中的一個(gè)重要任務(wù),它的目標(biāo)是將圖像劃分為多個(gè)區(qū)域或者對象,例如分割出物體、前景背景或特定的部分。在 Python 中,常用的圖片分割方法包括傳統(tǒng)的圖像處理技術(shù)(例如閾值分割、區(qū)域生長等)和深度學(xué)習(xí)技術(shù)(例如基于預(yù)訓(xùn)練模型的語義分割或?qū)嵗指睿?。以下是詳?xì)介紹和示例代碼:
1. 基于傳統(tǒng)圖像處理的分割方法
(1) 使用固定閾值分割圖片
使用 OpenCV 的閾值處理來將前景和背景分離。適合簡單的二值圖像。
import cv2 import numpy as np # 加載圖片 image = cv2.imread('image.jpg', 0) # 以灰度加載圖片 # 應(yīng)用二值化閾值分割 _, binary = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY) # 顯示分割結(jié)果 cv2.imshow('Original Image', image) cv2.imshow('Binary Image', binary) cv2.waitKey(0) cv2.destroyAllWindows()
參數(shù)說明:
128 是閾值,低于此值的像素設(shè)置為 0,高于閾值的設(shè)置為 255。
cv2.THRESH_BINARY 是二值化模式。
(2) 自適應(yīng)閾值分割
適合光照不均的情況,使用局部區(qū)域的像素值計(jì)算閾值。
import cv2 # 加載圖片 image = cv2.imread('image.jpg', 0) # 自適應(yīng)閾值分割 binary_adaptive = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY, 11, 2) # 顯示分割結(jié)果 cv2.imshow('Adaptive Threshold', binary_adaptive) cv2.waitKey(0) cv2.destroyAllWindows()
參數(shù)說明:
cv2.ADAPTIVE_THRESH_GAUSSIAN_C 使用高斯加權(quán)的鄰域計(jì)算閾值。
11 是鄰域大小。
2 是閾值偏移。
(3) 使用圖像邊緣檢測分割
通過檢測圖像的邊緣將不同的區(qū)域分離。
import cv2 # 加載圖片 image = cv2.imread('image.jpg', 0) # 使用Canny邊緣檢測 edges = cv2.Canny(image, 100, 200) # 顯示邊緣分割結(jié)果 cv2.imshow('Edge Detection', edges) cv2.waitKey(0) cv2.destroyAllWindows()
參數(shù)說明:
100 是低閾值,200 是高閾值,用于檢測邊緣。
(4) 基于 K-Means 的聚類分割
可以將圖像的顏色或亮度聚類為K個(gè)類別,適合彩色圖像分割。
import cv2 import numpy as np # 加載圖片 image = cv2.imread('image.jpg') image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) Z = image.reshape((-1, 3)) # 將圖像從二維展開為一維 # 使用 K-Means 聚類 Z = np.float32(Z) criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) K = 3 # 聚類數(shù) _, labels, centers = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS) # 將聚類結(jié)果映射回圖像 centers = np.uint8(centers) segmented_image = centers[labels.flatten()] segmented_image = segmented_image.reshape(image.shape) # 顯示分割結(jié)果 import matplotlib.pyplot as plt plt.imshow(segmented_image) plt.show()
參數(shù)說明:
K 是分割的顏色聚類數(shù),譬如設(shè)置為3會(huì)將圖像分割成3種顏色區(qū)域。
2. 深度學(xué)習(xí)分割方法
對于復(fù)雜分割任務(wù),深度學(xué)習(xí)可以提供更高的精度。典型方法包括使用預(yù)訓(xùn)練的分割模型(如 DeepLab、Mask R-CNN 等)。
(1) 使用 OpenCV DNN 模塊加載預(yù)訓(xùn)練的 DeepLabV3+ 模型
DeepLabV3+ 是一種流行的語義分割模型。
import cv2 import numpy as np # 加載 DeepLabV3+ 模型 net = cv2.dnn.readNetFromTensorflow('deeplabv3.pb') # 加載圖像 image = cv2.imread('image.jpg') blob = cv2.dnn.blobFromImage(image, scalefactor=1.0/255, size=(513, 513), mean=(127.5, 127.5, 127.5), swapRB=True, crop=False) # 推理 net.setInput(blob) output = net.forward() # 解析結(jié)果 segmentation_map = np.argmax(output[0], axis=0) # 顯示分割結(jié)果 segmentation_map = cv2.resize(segmentation_map.astype(np.uint8), (image.shape[1], image.shape[0])) cv2.imshow("Segmentation Map", segmentation_map) cv2.waitKey(0) cv2.destroyAllWindows()
(2) 使用 PyTorch 或 TensorFlow 加載分割模型
如果需要靈活的操作,可以使用深度學(xué)習(xí)框架加載分割模型進(jìn)行推理。
import torch from torchvision import models from torchvision import transforms from PIL import Image import matplotlib.pyplot as plt ???????# 加載預(yù)訓(xùn)練的 DeepLabV3 模型 model = models.segmentation.deeplabv3_resnet101(pretrained=True) model.eval() # 加載圖片并預(yù)處理 image = Image.open("image.jpg") transform = transforms.Compose([ transforms.ToTensor(), transforms.Resize((520, 520)), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) input_image = transform(image).unsqueeze(0) # 推理 output = model(input_image)['out'][0] segmentation_map = torch.argmax(output, dim=0).numpy() # 顯示分割結(jié)果 plt.imshow(segmentation_map) plt.show()
cv2.threshold(), cv2.adaptiveThreshold(), cv2.Canny(),cv2.kmeans() 函數(shù)詳解
1.cv2.threshold()
作用:圖像二值化,將灰度圖像轉(zhuǎn)為黑白圖像或多級(jí)閾值圖像。
retval, dst = cv2.threshold(src, thresh, maxval, type)
參數(shù)說明:
src: 輸入圖像,必須是灰度圖(單通道,uint8 類型)。
thresh: 閾值,將灰度圖中的像素值與該閾值進(jìn)行比較。
maxval: 如果滿足閾值規(guī)則,輸出像素值將設(shè)置為該值。
type: 閾值類型,有以下幾種:
- 1、cv2.THRESH_BINARY: 大于閾值的像素置為 maxval,否則置為 0。
- 2、cv2.THRESH_BINARY_INV: 小于閾值的像素置為 maxval,否則置為 0。
- 3、cv2.THRESH_TRUNC: 大于閾值的像素置為閾值,否則保持原值。
- 4、cv2.THRESH_TOZERO: 小于閾值的像素置為 0,否則保持原值。
- 5、cv2.THRESH_TOZERO_INV: 大于閾值的像素置為 0,否則保持原值。
主要用途:
圖像二值化(將物體與背景分離)。
特定場景下的簡單圖像分割。
2.cv2.adaptiveThreshold()
作用:圖像局部自適應(yīng)二值化,根據(jù)局部區(qū)域內(nèi)的灰度值確定閾值。這種方法在光照條件不均勻的情況下很有優(yōu)勢。
dst = cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
參數(shù)說明:
src: 輸入圖像,必須是灰度圖。
maxValue: 滿足閾值條件的像素的賦值。
adaptiveMethod: 自適應(yīng)閾值算法,有以下兩種:
cv2.ADAPTIVE_THRESH_MEAN_C: 閾值是局部窗口的平均值減去 C。
cv2.ADAPTIVE_THRESH_GAUSSIAN_C: 閾值是局部窗口的加權(quán)平均值減去 C。
thresholdType: 閾值類型(通常為 cv2.THRESH_BINARY 或 cv2.THRESH_BINARY_INV)。
blockSize: 局部區(qū)域的尺寸,必須為奇數(shù)(如 3、5、11)。
C: 從局部平均值中減去常數(shù) C。
主要用途:
- 圖像自適應(yīng)二值化。
- 光照不均情況下的前景分離。
3.cv2.Canny()
作用:邊緣檢測,采用 Canny 算法從圖像中提取顯著邊緣。
dst = cv2.Canny(image, threshold1, threshold2[, apertureSize[, L2gradient]])
參數(shù)說明:
image: 輸入圖像,需為灰度圖。
threshold1: 較小的閾值,用于邊緣連接。
threshold2: 較大的閾值,用于檢測顯著邊緣。
apertureSize: Sobel 算子的核大小,默認(rèn)值為 3。通常是 3, 5, 7。
L2gradient: 是否使用更精確的 L2 范數(shù)計(jì)算梯度,默認(rèn)為 False
主要用途:
圖像邊緣提取。
準(zhǔn)備圖像分割的輪廓信息。
4.cv2.kmeans()
作用:基于 K-Means 算法對輸入數(shù)據(jù)進(jìn)行聚類,適合圖像顏色分割或亮度分割。
retval, labels, centers = cv2.kmeans(data, K, bestLabels, criteria, attempts, flags)
參數(shù)說明:
data: 輸入數(shù)據(jù)(通常是圖像的像素值矩陣,需轉(zhuǎn)換為 np.float32)。
K: 聚類數(shù),即分割的類別數(shù)量。
bestLabels: 初始標(biāo)簽(通常為 None)。
criteria: K-Means 的終止條件,例如迭代次數(shù)或誤差:
(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, max_iter, epsilon)。
max_iter 是最大迭代次數(shù),epsilon 是誤差容忍度。
attempts: 嘗試執(zhí)行 K-Means 聚類的次數(shù),輸出至少達(dá)到局部最優(yōu)解。
flags: 初始化中心的方法,常用:
cv2.KMEANS_PP_CENTERS: 使用 K-Means++ 初始化中心點(diǎn)。
cv2.KMEANS_RANDOM_CENTERS: 使用隨機(jī)選擇初始化中心點(diǎn)。
cv2.dnn.blobFromImage(),transforms.Compose()函數(shù)詳解
1.cv2.dnn.blobFromImage()
功能:
cv2.dnn.blobFromImage() 是 OpenCV 的 DNN(深度學(xué)習(xí))模塊中的方法,用于將輸入圖像轉(zhuǎn)換為深度學(xué)習(xí)模型可以接受的標(biāo)準(zhǔn)化張量(“blob”)。具體包括:
重新調(diào)整圖像大小。
歸一化圖像像素(例如縮放到 [0,1] 或減去均值)。
轉(zhuǎn)換通道順序(例如將圖片從 BGR 轉(zhuǎn)換為 RGB)。
轉(zhuǎn)換維度順序(從 HWC -> CHW,即 [高度, 寬度, 通道] -> [通道, 高度, 寬度])。
cv2.dnn.blobFromImage(image, scalefactor=1.0, size=(width, height), mean=(meanR, meanG, meanB), swapRB=True, crop=False)
參數(shù)說明:
- image: 輸入圖像,通常是三通道(BGR)圖像或單通道圖像。
- scalefactor: 縮放因子,用于將像素值歸一化。例如,設(shè)置 scalefactor=1/255 將像素值從 [0,255] 縮放到 [0,1]。
- size: 重新調(diào)整后的圖像尺寸,通常根據(jù)模型的輸入需求設(shè)置(如 (224, 224))。
- mean: 均值,用于歸一化(針對每個(gè)通道減去均值)。例如:(meanR, meanG, meanB)。
- swapRB: 是否交換 R 和 B 通道(將 BGR 轉(zhuǎn)為 RGB),默認(rèn)為 True。
- crop: 是否在調(diào)整大小后裁剪圖像,如果為 True,會(huì)將圖像裁剪到目標(biāo)大小。
返回值:
返回一個(gè)預(yù)處理后的 blob,即一個(gè)多維的 numpy 數(shù)組,形狀通常為:
[batch_size, channels, height, width]
對單張圖像而言,batch_size = 1。
import cv2 # 讀取圖像(通常是 BGR 格式) image = cv2.imread('image.jpg') # 創(chuàng)建 blob blob = cv2.dnn.blobFromImage(image, scalefactor=1/255.0, size=(224, 224), mean=(0, 0, 0), swapRB=True, crop=False) # 輸出 blob 的形狀:通常為 (1, 3, 224, 224),對應(yīng) [batch, channels, height, width] print("Blob shape:", blob.shape) # 將 blob 傳入模型 # net.setInput(blob) # output = net.forward()
常見參數(shù)設(shè)置:
- 歸一化:如果模型輸入要求的像素范圍是 [0, 1],可以通過 scalefactor = 1/255 實(shí)現(xiàn)歸一化。
- 均值減法:一些預(yù)訓(xùn)練模型會(huì)要求每個(gè)通道的均值為特定值,如 (123.68, 116.78, 103.94)(VGG 或 ResNet 等常用)。
- 圖像尺寸:目標(biāo)模型的輸入尺寸通常固定,如 (224, 224) 或 (300, 300)。
2.transforms.Compose()
功能:
transforms.Compose() 是 PyTorch 的 torchvision.transforms 模塊中的方法,用來對圖像數(shù)據(jù)進(jìn)行多步組合式處理,例如裁剪、縮放、歸一化等。它允許將多個(gè)圖像變換操作(transforms)鏈接在一起。
transforms.Compose([transform1, transform2, ..., transformN])
參數(shù)說明:
- transform1, transform2, …, transformN:每個(gè)變換操作都是一個(gè) torchvision.transforms 的實(shí)例。 例如:
- transforms.Resize(size): 縮放圖像到指定大小。
- transforms.CenterCrop(size): 從圖像中央裁剪到指定大小。
- transforms.Normalize(mean, std): 標(biāo)準(zhǔn)化張量,減去均值并除以標(biāo)準(zhǔn)差。
- transforms.ToTensor(): 將圖像從 PIL 格式轉(zhuǎn)換為 PyTorch 張量,并歸一化到 [0, 1] 范圍。
- transforms.RandomHorizontalFlip§: 隨機(jī)水平翻轉(zhuǎn),概率為 p。
使用場景:
用于對圖像數(shù)據(jù)的批量預(yù)處理,尤其是在訓(xùn)練深度學(xué)習(xí)模型前對數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化和增強(qiáng)處理。
import torch from torchvision import transforms from PIL import Image # 加載圖像 image = Image.open("image.jpg") # 定義數(shù)據(jù)變換 data_transforms = transforms.Compose([ transforms.Resize((224, 224)), # 調(diào)整大小到 (224, 224) transforms.ToTensor(), # 轉(zhuǎn)為 PyTorch 張量 transforms.Normalize(mean=[0.485, 0.456, 0.406], # 按通道歸一化 (均值減去) std=[0.229, 0.224, 0.225]) # 按通道歸一化 (標(biāo)準(zhǔn)差除以) ]) ???????# 對圖像應(yīng)用變換 tensor_image = data_transforms(image) # 檢查結(jié)果 print("Tensor shape:", tensor_image.shape) # 通常為 (3, 224, 224) print("Tensor values (normalized):", tensor_image)
常用的變換操作:
組合數(shù)據(jù)增強(qiáng)處理示例:
import torchvision.transforms as transforms from PIL import Image ???????# 加載圖像 image = Image.open("image.jpg") # 定義數(shù)據(jù)增強(qiáng)變換 data_transforms = transforms.Compose([ transforms.RandomRotation(30), # 隨機(jī)旋轉(zhuǎn) ±30 度 transforms.RandomHorizontalFlip(p=0.5), # 隨機(jī)水平翻轉(zhuǎn) 50% 概率 transforms.ColorJitter(brightness=0.2, contrast=0.3), # 隨機(jī)調(diào)整亮度和對比度 transforms.Resize((224, 224)), # 調(diào)整大小到 (224, 224) transforms.ToTensor(), # 轉(zhuǎn)為 PyTorch 張量 ]) # 應(yīng)用變換 tensor_image = data_transforms(image) print("Augmented Tensor Shape:", tensor_image.shape)
cv2.dnn.blobFromImage() vs transforms.Compose()
這兩者主要是針對不同框架的圖像預(yù)處理功能:
cv2.dnn.blobFromImage() :主要用于 OpenCV DNN 模型,側(cè)重于將輸入格式標(biāo)準(zhǔn)化為深度學(xué)習(xí)模型的張量。
transforms.Compose() :是 PyTorch 的高級(jí)操作,用于批量構(gòu)造靈活的數(shù)據(jù)增強(qiáng)和標(biāo)準(zhǔn)化流程。
到此這篇關(guān)于Python實(shí)現(xiàn)圖片分割的多種方法總結(jié)的文章就介紹到這了,更多相關(guān)Python圖片分割內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)的一個(gè)簡單LRU cache
這篇文章主要介紹了Python實(shí)現(xiàn)的一個(gè)簡單LRU cache,本文根據(jù)實(shí)際需求總結(jié)而來,需要的朋友可以參考下2014-09-09python使用pip安裝模塊出現(xiàn)ReadTimeoutError: HTTPSConnectionPool的解決方法
這篇文章主要介紹了python使用pip安裝模塊出現(xiàn)ReadTimeoutError: HTTPSConnectionPool的解決方法,需要的朋友可以參考下2019-10-10python神經(jīng)網(wǎng)絡(luò)InceptionV3模型復(fù)現(xiàn)詳解
這篇文章主要為大家介紹了python神經(jīng)網(wǎng)絡(luò)InceptionV3模型復(fù)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-05-05python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽事件處理機(jī)制詳細(xì)介紹與實(shí)例解析
這篇文章主要介紹了python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽事件處理機(jī)制詳細(xì)介紹與實(shí)例解析,需要的朋友可以參考下2020-03-03python詞云庫wordcloud的使用方法與實(shí)例詳解
這篇文章主要介紹了python詞云庫wordcloud的使用方法與實(shí)例詳解,需要的朋友可以參考下2020-02-02