Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中创建圆以遮罩图像并计算每个圆内的像素数_Python_Image_Image Processing - Fatal编程技术网

在python中创建圆以遮罩图像并计算每个圆内的像素数

在python中创建圆以遮罩图像并计算每个圆内的像素数,python,image,image-processing,Python,Image,Image Processing,在python中,我试图将一个图像分割成圆圈,并计算每个圆圈中黑色像素的数量 例如,我有一张用鱼眼镜头(半球形图像)拍摄的图像(下面画出例子),我想把图像分割成小圆圈,从中间的一个小圆圈到整个图像捕捉图像的一部分。 我想将图像分割成x个圆圈,每次捕获图像的一部分(见下图) 一旦我有了圆形图像,我就可以计算出每个图像中的像素数 我试过: Image=Image.new(“RGB”,(20002000)) draw=ImageDraw.draw(图像) 绘制椭圆((20,2018001800),

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

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

我想将图像分割成x个圆圈,每次捕获图像的一部分(见下图)

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

我试过:
Image=Image.new(“RGB”,(20002000))
draw=ImageDraw.draw(图像)
绘制椭圆((20,2018001800),填充(255255255)

然后用它创建了一个遮罩,但是不管我如何更改draw.ellipse中的数字。这个圆只捕获了整个图像,但使图像本身变小了


如果您有任何关于如何解决此问题的想法或建议,我们将不胜感激。

您应该在OpenCV上查找此类任务。您可以将圆转换为整个轮廓并计算圆的半径。然后您可以绘制圆并将其绘制在遮罩上,然后执行
cv2.按位和
以使圆在图像上具有ROI。您可以用你选择的整数(在我的例子中是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
导入cv2
将numpy作为np导入
img=cv2.imread('circle.png')
h、 w=图像形状[:2]
掩码=np.0((h,w),np.uint8)
灰色=cv2.CVT颜色(img,cv2.COLOR\U BGR2GRAY)
_,thresh=cv2.阈值(灰色,0255,cv2.thresh_二进制+cv2.thresh_大津)
kernel=np.one((10,10),np.uint8)
opening=cv2.morphologyEx(thresh,cv2.MORPH\u CLOSE,kernel,迭代次数=2)
_,等高线,层次=cv2.findContours(开口,cv2.RETR\u树,cv2.CHAIN\u近似值\u无)
cnt=最大值(轮廓,关键点=cv2.轮廓面积)
extLeft=tuple(cnt[cnt[:,:,0].argmin()][0])
extRight=tuple(cnt[cnt[:,:,0].argmax()][0])
半径=(外向[0]-外向左[0])/2
打印(右外[0],左外[0])
打印(半径)
M=cv2.力矩(cnt)
cx=int(M['m10']/M['m00']
cy=int(M['m01']/M['m00']
打印(cx、cy)
对于范围(1,30)内的i:

如果我*10这在纯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)

谢谢你的代码,它看起来很棒,我试过了,但是不幸的是,图像真的很大,圆没有出现在屏幕中间。有什么原因吗?你能张贴这张照片吗?试着做一个更大的内核(20,20,30,30)。-如果内核大小太小,可能不会生成一个轮廓,因此中间点不同感谢您的快速回复,我已将图像添加到上述问题中,因为我不确定如何将图像添加到评论部分。将内核变大并不能解决问题。我的意思是,如果您可以添加原始的“大”没有任何处理的图像,谢谢你的帮助。我已经上传了我正在运行的代码的测试图像,但是在图像中间的小圆圈的问题仍然在发生。
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
# 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)
fake_im_arr[center[0] - radius:center[0] + (radius + 1),
            center[1] - radius:center[1] + (radius + 1)]

array([[0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1],
       [0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1],
       [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1],
       [1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1],
       [1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0],
       [0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1],
       [1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0],
       [0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0],
       [1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0]])

mask[center[0] - radius:center[0] + (radius + 1),
     center[1] - radius:center[1] + (radius + 1)].astype('int')

array([[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]])

np.where(mask, fake_im_arr, 0)[center[0] - radius:center[0] + (radius + 1),
                               center[1] - radius:center[1] + (radius + 1)]

array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0],
       [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0],
       [0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0],
       [1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1],
       [0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0],
       [0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0],
       [0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0],
       [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]])