我有一个图像,我想处理它。我正在使用 Opencv 和 skimage。我的目标是找到所有点的重心周围的红点分布。我进行如下操作:首先选择颜色,然后对获得的图像进行二值化。最终,我只计算围绕该重心具有一定宽度的环上的红色像素,以便在假设圆柱对称的情况下获得关于半径的平均分布。
我的问题是我不知道如何找到重心的位置。
我还想知道是否有一种简单的方法来计算环中的红色像素。
这是我的代码:
import cv2
import matplotlib.pyplot as plt
from skimage import io, filters, measure, color, external
我正在上传图片:
sph = cv2.imread('image_sper.jpg')
sph = cv2.cvtColor(sph, cv2.COLOR_BGR2RGB)
plt.imshow(sph)
plt.show()
我想选择红色。关注 https://realpython.com/python-opencv-color-spaces/ ,我正在将它转换为 HSV,并且我正在使用掩码。
hsv_sph = cv2.cvtColor(sph, cv2.COLOR_RGB2HSV)
light_red = (1, 100, 100)
dark_red = (18, 255, 255)
mask = cv2.inRange(hsv_sph, light_red, dark_red)
result = cv2.bitwise_and(sph, sph, mask=mask)
这是结果:
plt.imshow(result)
plt.show()
现在我正在对图像进行二值化,因为之后处理它会更容易。
red_image = result[:,:,1]
red_th = filters.threshold_otsu(red_image)
red_mask = red_image > red_th;
red_mask.dtype ;
io.imshow(red_mask);
我们在这里:
我现在想要一些帮助来找到白色像素的重心。
谢谢
编辑:二值化为像素提供图像 bool 值 False/True。我不知道如何将它们转换为 0/1 像素。如果 False 为 0,True 1,则查找重心的代码为:
np.shape(red_mask)
(* (321L, 316L) *)
bari=0
barj=0
N=0
for i in range(321):
for j in range(316):
bari=bari+red_mask[i,j]*i
barj=barj+red_mask[i,j]*j
N=N+red_mask[i,j]
bari=bari/N
barj=barj/N
最佳答案
另一个应该在这里问的问题:http://answers.opencv.org/questions/
但是,我们走吧!
我实现的过程主要使用结构分析(https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a)
首先我得到了你的图像:
import cv2
import matplotlib.pyplot as plt
import numpy as np
from skimage import io, filters, measure, color, external
sph = cv2.imread('points.png')
ret,thresh = cv2.threshold(sph,200,255,cv2.THRESH_BINARY)
然后腐 eclipse 并转换为降噪
kernel = np.ones((2,2),np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
opening = cv2.cvtColor(opening, cv2.COLOR_BGR2GRAY);
opening = cv2.convertScaleAbs(opening)
然后使用“cv::findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())”查找所有blob。
之后,只需计算每个区域的中心,并根据轮廓区域进行加权平均。这样,我得到了点质心(X:143.4202820443726,Y:154.56471750651224)。
im2, contours, hierarchy = cv2.findContours(opening, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
areas = []
centersX = []
centersY = []
for cnt in contours:
areas.append(cv2.contourArea(cnt))
M = cv2.moments(cnt)
centersX.append(int(M["m10"] / M["m00"]))
centersY.append(int(M["m01"] / M["m00"]))
full_areas = np.sum(areas)
acc_X = 0
acc_Y = 0
for i in range(len(areas)):
acc_X += centersX[i] * (areas[i]/full_areas)
acc_Y += centersY[i] * (areas[i]/full_areas)
print (acc_X, acc_Y)
cv2.circle(sph, (int(acc_X), int(acc_Y)), 5, (255, 0, 0), -1)
plt.imshow(sph)
plt.show()
关于python - 如何使用 opencv/skimage 在 python 上找到图案的中心及其周围颜色的分布?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54425093/