当我进行粒子扫描分析时,我最终采用了类似PCA的方法:
%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
import cv2
im = cv2.imread("mask.png", 0) # read as gray
y, x = np.where(im) # get non-zero elements
centroid = np.mean(x), np.mean(y) # get the centroid of the particle
x_diff = x - centroid[0] # center x
y_diff = y - centroid[1] # center y
cov_matrix = np.cov(x_diff, y_diff) # get the convariance
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix) # apply EVD
indicesForSorting = np.argsort(eigenvalues)[::-1] # sort to get the primary first
eigenvalues = eigenvalues[indicesForSorting]
eigenvectors = eigenvectors[:, indicesForSorting]
plt.figure()
plt.imshow(im, cmap = "gray") # plot image
vecPrimary = eigenvectors[:, 0] * np.sqrt(eigenvalues[0])
plt.plot([centroid[0] - vecPrimary[0], centroid[0] + vecPrimary[0]],
[centroid[1] - vecPrimary[1], centroid[1] + vecPrimary[1]])
vecSecondary = eigenvectors[:, 1] * np.sqrt(eigenvalues[1])
plt.plot([centroid[0] - vecSecondary[0], centroid[0] + vecSecondary[0]],
[centroid[1] - vecSecondary[1], centroid[1] + vecSecondary[1]])
我喜欢这种方法,因为它也扩大了界限.如果您不希望这样做,您可以获得这条线的Angular 并绘制无限Angular ,然后用图像将其遮盖.希望这对您有进一步帮助
编辑:用开放画线
### same analysis as before
im = cv2.imread("mask.png")
pt1 = (int(centroid[0] - vecPrimary[0]), int(centroid[1] - vecPrimary[1]))
pt2 = (int(centroid[0] + vecPrimary[0]), int(centroid[1] + vecPrimary[1]))
cv2.line(im, pt1, pt2, (255, 0, 0), 2) # blue line
pt1 = (int(centroid[0] - vecSecondary[0]), int(centroid[1] - vecSecondary[1]))
pt2 = (int(centroid[0] + vecSecondary[0]), int(centroid[1] + vecSecondary[1]))
cv2.line(im, pt1, pt2, (0, 0, 255), 2) # redline
cv2.imwrite("maskWithLines.png", im)
结果:
编辑:正如我在回答中所说,只需将这些载体乘以一个比例,然后使用屏蔽为biwise_and
:
im = cv2.imread("mask.png")
imGray = cv2.imread("mask.png", 0) # read imgray
y, x = np.where(imGray) # get non-zero elements
centroid = np.mean(x), np.mean(y) # get the centroid of the particle
x_diff = x - centroid[0] # center x
y_diff = y - centroid[1] # center y
cov_matrix = np.cov(x_diff, y_diff) # get the convariance
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix) # apply EVD
indicesForSorting = np.argsort(eigenvalues)[::-1] # sort to get the primary first and secondary second
eigenvalues = eigenvalues[indicesForSorting] # sort eigenvalues
eigenvectors = eigenvectors[:, indicesForSorting] # sort eigenvectors
Scale = 100 # this can be adjusted, iut is actually not important as long as it is a very high value
vecPrimary = eigenvectors[:, 0] * np.sqrt(eigenvalues[0]) * Scale
vecSecondary = eigenvectors[:, 1] * np.sqrt(eigenvalues[1]) * Scale
pt1 = (int(centroid[0] - vecPrimary[0]), int(centroid[1] - vecPrimary[1]))
pt2 = (int(centroid[0] + vecPrimary[0]), int(centroid[1] + vecPrimary[1]))
cv2.line(im, pt1, pt2, (255, 0, 0), 2) # blue line
pt1 = (int(centroid[0] - vecSecondary[0]), int(centroid[1] - vecSecondary[1]))
pt2 = (int(centroid[0] + vecSecondary[0]), int(centroid[1] + vecSecondary[1]))
cv2.line(im, pt1, pt2, (0, 0, 255), 2) # red line
im = cv2.bitwise_and(im, im, mask = imGray) # mask the lines
cv2.imwrite("maskWithLines.png", im)
结果如下: