我正在尝试拍摄这样的图像,只包含灰度图像:
然后,我想检索并将所述图像的轮廓保存到.npy
文件中,逐层迭代,直到图像不再存在。不幸的是,虽然合成轮廓有效,但它们的合成力矩为零
为了处理图像周围的黑色空间,我实现了一个裁剪所有空白空间的基本算法:检索图像中任何空间的所有轮廓,然后裁剪到所述轮廓的x和y坐标。该算法在名为FrontImage
的类中实现,如下所示:
class FrontImage:
def __init__(self, img, lh):
self.image = img
self.layer_height = lh
self.objs = self.getObjs()
self.extrema = self.getExtrema()
# gets the list of "objects" (read: contours) in the image
def getObjs(self):
# canny edge
edged = cv2.Canny(self.image.copy(), 30, 200)
# get contours from edged image
cnts, hier = cv2.findContours(edged.copy(), \
cv2.RETR_EXTERNAL, \
cv2.CHAIN_APPROX_NONE)
if (cnts is not None) and (len(cnts) > 0):
# sort by area [for no real reason]
cnts = sorted(cnts, key=cv2.contourArea)
# return final list of objects
return [DetectedObject(c) for c in cnts]
# retrieves the extrema for later cropping
def getExtrema(self):
# get list of all extrema from all objects
left_ext = [obj.extrema()[0] for obj in self.objs]
right_ext = [obj.extrema()[1] for obj in self.objs]
top_ext = [obj.extrema()[2] for obj in self.objs]
bottom_ext = [obj.extrema()[3] for obj in self.objs]
# sort by greatest values in respective directions
max_x_ext = sorted(right_ext, key=lambda e: e[0])[-1]
min_x_ext = sorted(left_ext, key=lambda e: e[0])[0]
max_y_ext = sorted(top_ext, key=lambda e: e[1])[0]
min_y_ext = sorted(bottom_ext, key=lambda e: e[1])[-1]
return (max_x_ext, min_x_ext, max_y_ext, min_y_ext)
# gets the xy size of the image
def size(self):
x_size = self.extrema[0][0] - self.extrema[1][0]
y_size = int(np.floor((self.extrema[3][1] - self.extrema[2][1]) / self.layer_height))
return (x_size, y_size)
# crops the image based on extrema bounds and "height" to remove
def crop(self, layers):
# int(np.floor(()) converts it to a consistently "underapproximated" integer
return FrontImage(self.image[int(np.floor(self.extrema[2][1]+self.layer_height*layers)):\
self.extrema[3][1], \
self.extrema[1][0]:self.extrema[0][0]], self.layer_height)
与这些极值相关的极值和等高线存储在一个名为DetectedObject
的类中:
class DetectedObject:
def __init__(self, cnt):
self.contour = cnt
def draw(self, img):
cv2.drawContours(img, self.contour, -1, (0, 255, 0), 3)
# returns the top extrema of the contour
def extrema(self):
left = tuple(self.contour[self.contour[:, :, 0].argmin()][0])
right = tuple(self.contour[self.contour[:, :, 0].argmax()][0])
top = tuple(self.contour[self.contour[:, :, 1].argmin()][0])
bottom = tuple(self.contour[self.contour[:, :, 1].argmax()][0])
return (left, right, top, bottom)
问题是,当我在img.crop()
上进行迭代时,就像这样:
img = FrontImage(cv2.imread(image), lh).crop(0)
i = 0
meta_cnts = []
while i < img.size()[1]:
# grab the contour data and append it to the metalist
imgn = img.crop(i)
print(cv2.moments(imgn.objs[0].contour))
meta_cnts.append(imgn.objs[0].contour)
i += 1
np.save("contours", meta_cnts)
轮廓的所有合成力矩均为零!这不会在其他类似方式的图像中再次出现,但在这个奇异立方体中,所有的瞬间都是零:
λ src/crunchwrap/model python main.py xyzCalibration_cube.obj
{'m00': 0.0, 'm10': 0.0, 'm01': 0.0, 'm20': 0.0, 'm11': 0.0, 'm02': 0.0, 'm30': 0.0, 'm21': 0.0, 'm12': 0.0, 'm03
': 0.0, 'mu20': 0.0, 'mu11': 0.0, 'mu02': 0.0, 'mu30': 0.0, 'mu21': 0.0, 'mu12': 0.0, 'mu03': 0.0, 'nu20': 0.0, '
nu11': 0.0, 'nu02': 0.0, 'nu30': 0.0, 'nu21': 0.0, 'nu12': 0.0, 'nu03': 0.0}
(this continues for some time with the same output)
在Linux上运行OpenCV 4.2.0和Python 3.8.1。 如果这个问题太冗长,我深表歉意。谢谢你的帮助
我设法通过重构
FrontImage
来解决这个问题,以避免每次都进行智能裁剪,并且只在初始运行时进行,例如:相关问题 更多 >
编程相关推荐