在一个python图像中创建一个ci和一个像素

2024-09-30 18:25:32 发布

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

在python中,我尝试将一个图像分割成多个圆,并计算每个圆中黑色像素的数量。在

例如,我有一个用鱼眼镜头拍摄的图像(半球形的图像)(下面画的例子),我想把图像分成小圆,捕捉图像的一部分,从中间的一个小圆到整个图像。 picture of a captured image

我想把图像分割成x个圆圈,每次捕捉图像的一部分(见下图) circle 1circle 2

一旦我有了圆形图像,我就可以计算出每个图像中的像素数。在

我试过了: Image=Image.new("RGB", (2000,2000)) draw = ImageDraw.Draw(image) draw.ellipse((20,20,1800,1800),fill(255,255,255)

然后从中创建了一个掩码,不管我如何更改绘图.椭圆圆圈只会捕捉到整个图像,但会使图像本身变小。在

任何关于如何解决这个问题的想法或建议都将不胜感激!在


Tags: 图像imagenew数量rgb像素圆形例子
2条回答

如果您对库足够熟悉,那么在纯numpy中这是最简单的方法:

# Create some fake data
np.random.seed(100)
fake_im_arr = np.random.randint(low=0, high=2, size=(2000,2000))

# Function definition for creating masks
def create_circle_mask(X_arr, Y_arr, center, radius):
    c_x, c_y = center
    dists_sqrd = (X_arr - c_x)**2 + (Y_arr - c_y)**2
    return dists_sqrd <= radius**2

# Using the two together:
center, radius = (1000, 1000), 5
size_x, size_y = fake_im_arr.shape
mask = create_circle_mask(*np.ogrid[0:size_x, 0:size_y], center=center, radius=radius)
n_black_in_circle = ((fake_im_arr == 1) & mask).sum() # This is your answer (39 in this case)

要查看各种阵列的外观:

^{pr2}$

对于这些任务,您应该查看OpenCV。您可以将圆转换为整个轮廓并计算圆的半径。然后你可以画圆,在蒙版上画出它们,然后执行cv2.bitwise_and在图像上画出圆形感兴趣区域。你可以用你选择的一个整数(在我的例子中是10)来迭代和多个ROI圆的半径。希望有帮助。干杯!在

示例代码:

import cv2
import numpy as np

img = cv2.imread('circle.png')
h, w = img.shape[:2]
mask = np.zeros((h, w), np.uint8)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
kernel = np.ones((10,10),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel, iterations = 2)
_, contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)
extLeft = tuple(cnt[cnt[:, :, 0].argmin()][0])
extRight = tuple(cnt[cnt[:, :, 0].argmax()][0])
radius = (extRight[0] - extLeft[0])/2
print(extRight[0], extLeft[0])
print(radius)

M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
print(cx, cy)

for i in range(1,30):
    if i*10<radius:
        print(i*10)
        cv2.circle(mask,(cx,cy), i*10, 255, -1)
        res = cv2.bitwise_and(img, img, mask=mask)
        pixels = np.sum(res == 255)
        cv2.putText(res,'Pixel count: '+str(pixels),(30,30), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255,255,255), 1, cv2.LINE_AA)
        cv2.imshow('img', res)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    else:
        res = cv2.bitwise_and(img, img, mask=opening)
        pixels = np.sum(res == 255)
        cv2.putText(img,'Pixel count: '+str(pixels),(30,30), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255,255,255), 1, cv2.LINE_AA)
        cv2.imshow('img', res)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        break

结果:

enter image description here

enter image description here

enter image description here

编辑:

尝试用不同的方法计算中间值

^{pr2}$

编辑2:

好吧,我从你的第一个例子中假设你的形象从一开始就几乎是一个圆。因为它不是你必须计算不同的中心(从我的第一个编辑-从边界框)和做一个更大的内核(40,40)-因为事实上,图像非常大。再加上你必须使我在范围内的阈值(如10000)。这将起作用:

import cv2
import numpy as np

img = cv2.imread('circleroi.jpg')
h, w = img.shape[:2]
mask = np.zeros((h, w), np.uint8)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
kernel = np.ones((40,40),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel, iterations = 2)

_, contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)
extLeft = tuple(cnt[cnt[:, :, 0].argmin()][0])
extRight = tuple(cnt[cnt[:, :, 0].argmax()][0])
radius = (extRight[0] - extLeft[0])/2

x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

cx = int(x+(w/2))
cy = int(y+h/2)

for i in range(1,10000):
    if i*10<radius:
        cv2.circle(mask,(cx,cy), i*10, 255, -1)
        res = cv2.bitwise_and(img, img, mask=mask)
        pixels = np.sum(res == 255)
        cv2.putText(res,'Pixel count: '+str(pixels),(30,30), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255,255,255), 1, cv2.LINE_AA)
        cv2.imshow('img', res)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    else:
        res = cv2.bitwise_and(img, img, mask=opening)
        pixels = np.sum(res == 255)
        cv2.putText(img,'Pixel count: '+str(pixels),(30,30), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255,255,255), 1, cv2.LINE_AA)
        cv2.imshow('img', res)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        break

相关问题 更多 >