确定图像给定圆形样本的平均颜色?

2024-05-16 11:01:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图实现的是类似于photoshop/gimp的滴管工具:在图像中给定区域取一个圆形样本,并返回该圆形样本的平均颜色。你知道吗

我发现的最简单的方法是取一个“规则的”正方形样本,将其遮罩为一个圆,然后将其缩小到1像素,但这对CPU的要求非常高(尤其是重复数百万次时)。你知道吗

一个更复杂的数学方法是取一个正方形区域,并仅对该样本中圆形区域内的像素进行平均,但确定哪个像素在该圆形区域内,重复,同样需要CPU。你知道吗

有没有更简洁,更少的CPU要求的手段来实现这一点?你知道吗


Tags: 工具方法图像区域颜色规则像素圆形
2条回答

我相信还有更简洁的方法,但是:

import math
import numpy as np
import imageio as ioimg # as scipy's i/o function is now depreciated
from skimage.draw import circle
import matplotlib.pyplot as plt


# base sample dimensions (rest below calculated on this). 
# Must be an odd number.
wh = 49
# tmp - this placement will be programmed later
dp = 500

#load work image (from same work directory)
img = ioimg.imread('830.jpg')
# convert to numpy array (droppying the alpha while we're at it)
np_img = np.array(img)[:,:,:3]
# take sample of resulting array
sample = np_img[dp:wh+dp, dp:wh+dp]

#==============
# set up numpy circle mask
## this mask will be multiplied against each RGB layer in extracted sample area

# set up basic square array
sample_mask = np.zeros((wh, wh), dtype=np.uint8)
# set up circle centre coords and radius values
xy, r = math.floor(wh/2), math.ceil(wh/2)
# use these values to populate circle area with ones
rr, cc = circle(xy, xy, r)
sample_mask[rr, cc] = 1
# add axis to make array multiplication possible (do I have to do this)
sample_mask = sample_mask[:, :, np.newaxis]

result = sample * sample_mask
# count number of nonzero values (this will be our median divisor)
nz = np.count_nonzero(sample_mask)

sample_color = []
for c in range(result.shape[2]):
    sample_color.append(int(round(np.sum(result[:,:,c])/nz)))


print(sample_color) # will return array like [225, 205, 170]
plt.imshow(result, interpolation='nearest')
plt.show()

resulting circle-sample 也许在这里问这个问题是没有必要的(我已经有一段时间没有编写python了,并且希望从那时起已经为此开发了一些新的库),但是我希望这可以为其他有同样目标的人提供参考。你知道吗

这个操作将对图像中的每一个像素(有时是数百万次)执行数千个图像(扫描的页面),因此这是我的性能问题的担心,但由于numpy,这个代码非常快。你知道吗

这里有一个skimage.draw.circle()的小例子,它实际上并不画圆,而是给出圆内点的坐标,可以用来索引Numpy数组。你知道吗

#!/usr/bin/env python3

import numpy as np
from skimage.io import imsave
from skimage.draw import circle

# Make rectangular canvas of mid-grey
w, h = 200, 100
img = np.full((h, w), 128, dtype=np.uint8)

# Get coordinates of points within a central circle
Ycoords, Xcoords = circle(h//2, w//2, 45)

# Make all points in circle=200, i.e. fill circle with 200
img[Ycoords, Xcoords] = 200

# Get mean of points in circle
print(img[Ycoords, Xcoords].mean())      # prints 200.0

# DEBUG: Save image for checking
imsave('result.png',img)

enter image description here

关键词:Numpy,skipage,scikit image,图像处理,Python,圆,draw,圆内点坐标,掩蔽平均值。你知道吗

相关问题 更多 >