[英]How to count number of white and black pixels in color picture in python? How to count total pixels using numpy
[英]How to retrieve a list of indexes of white pixels whose neighbor are black using Python PIL and Numpy?
我一直在尋找幾個小時來找到類似的問題,但沒有什么能讓我滿意。 我的問題是:我有一個 PIL 圖像(代表一條運河)已經轉換成一個 Numpy 數組(使用 PIL 的“L”模式),我想檢索其鄰居為黑色的白色像素(它們的索引在事實上),沒有使用for 循環(圖像真的很大)。 我想到了np.where但我不知道我應該如何使用它來解決我的問題,我也不知道它是否會比使用for 循環更快(因為我的目標是以最快的速度達到這個目標解決方案)。
我希望我足夠清楚,我提前感謝您的回復!
編輯:例如,對於這個圖像(一個簡單的運河,它已經是一個黑白圖像,所以image.convert('L')在這里並不是很有用,但如果可能的話代碼應該是通用的),我會做這樣的事情:
import numpy as np
from PIL import Image
image = Image.open(canal)
image = image.convert("L")
array = np.asarray(image)
l = []
for i in range(1, len(array) - 1):
for j in range(1, len(array[0]) - 1):
if array[i][j] == 255 and (array[i+1][j] == 0 or array[i-1][j] == 0 or array[i][j+1] == 0 or array[i][j-1] == 0):
l.append((i, j))
我希望盡快獲得l :) 我在下一張圖片中將我需要的像素標為紅色:此處。
EDIT2:謝謝大家的幫助,它成功了!
您可以使用numba
即時編譯器來加速循環。
from numba import njit
@njit
def find_highlow_pixels(img):
pixels = []
for j in range(1, img.shape[0]-1):
for i in range(1, img.shape[1]-1):
if (
img[j, i] == 255 and (
img[j-1, i]==0 or img[j+1,i]==0 or
img[j, i-1]==0 or img[j, i+1]==0
)
):
pixels.append((j, i))
return pixels
我想到的另一種可能性是使用最小過濾器。 但是,我預計它會比第一個提議的解決方案慢,但在其基礎上構建更多內容可能會有用。
import numpy as np
from scipy.ndimage import minimum_filter
# create a footprint that only takes the neighbours into account
neighbours = (np.arange(9) % 2 == 1).reshape(3,3)
# create a mask of relevant pixels, img should be your image as array
mask = np.logical_and(
img == 255,
minimum_filter(img, footprint=neighbours) == 0
)
# get indexes
indexes = np.where(mask)
# as list
list(zip(*indexes))
如果不考慮 memory 空間,我更喜歡像下面這樣的掩碼操作。
# Step 1: Generate two masks of white and black.
mask_white = img == 255
mask_black = img == 0
# Step 2: Apply 8-neighborhood dilation on black mask
# if you want to use numpy only, you need to implement dilation by yourself.
# define function of 8-neighborhood dilation
def dilate_8nb(m):
index_row, index_col = np.where(m)
ext_index_row = np.repeat(index_row,9)
ext_index_col = np.repeat(index_col,9)
ext_index_row.reshape(-1,9)[:, :3] += 1
ext_index_row.reshape(-1,9)[:, -3:] -= 1
ext_index_col.reshape(-1,9)[:, ::3] += 1
ext_index_col.reshape(-1,9)[:, 2::3] -= 1
ext_index_row = np.clip(ext_index_row, 0, m.shape[0]-1)
ext_index_col = np.clip(ext_index_col, 0, m.shape[1]-1)
ret = m.copy()
ret[ext_index_row, ext_index_col] = True
return ret
ext_mask_black = dilate_8nb(mask_black)
# or just using dilation in scipy
# from scipy import ndimage
# ext_mask_black = ndimage.binary_dilation(mask_black, structure=ndimage.generate_binary_structure(2, 2))
# Step 3: take the intersection of mask_white and ext_mask_black
mask_target = mask_white & ext_mask_black
# Step 4: take the index using np.where
l = np.where(mask_target)
# modify this type to make it consistency with your result
l = list(zip(*l))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.