python - 如何使用 opencv/skimage 在 python 上找到图案的中心及其周围颜色的分布?

标签 python opencv image-processing scikit-image

我有一个图像,我想处理它。我正在使用 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()

enter image description here

我想选择红色。关注 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()

enter image description here

现在我正在对图像进行二值化,因为之后处理它会更容易。
red_image = result[:,:,1]
red_th = filters.threshold_otsu(red_image)

red_mask = red_image > red_th;
red_mask.dtype ;
io.imshow(red_mask);

我们在这里:

enter image description here

我现在想要一些帮助来找到白色像素的重心。

谢谢

编辑:二值化为像素提供图像 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)

enter image description here

然后腐 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)

enter image description here

然后使用“cv::findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())”查找所有blob。

之后,只需计算每个区域的中心,并根据轮廓区域进行加权平均。这样,我得到了点质心(X:143.4202820443726,Y:154.56471750651224)。

enter image description here
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/

相关文章:

php - 使用 PHP 检测图像的主要阴影

python - 使用 pandas 将 Unix 13 位数字转换为日期时间/时间戳格式

c++ - opencv 中的 OCR - 如何传递对象

c++ - 低对比度图像分割

javascript - 仅使用接受 URL 作为输入的 JavaScript 裁剪照片

image-processing - OpenCV + 网络摄像头兼容性

python - "TypeError: native Qt signal is not callable"带有自定义插槽

python - 使用一天中的特定时间或小时过滤 Pandas 数据框

python - 操作错误 : "Unknown MySQL server host"

python - PIL : IOError: [Errno 13] Permission denied: [picturename. jpg]