Smart猫小萌
下面的代码做你想要的。首先,它将图像转换为 HSV 色彩空间,这使得选择颜色更加容易。接下来制作一个仅选择绿色部分的蒙版。去除了一些噪音并汇总了行和列。最后,基于绿色选择中的第一行/最后一行/列创建一个新图像。由于在所有提供的示例中需要裁剪掉一些额外的顶部,因此我添加了代码来做到这一点。首先,我倒置了面具。现在您可以使用行/列的总和来查找完全在绿色选择范围内的行/列。它是为顶部完成的。在窗口下方的图像中,“Roi2”是最终图像。编辑:ts 评论后更新代码。更新结果:代码:import numpy as np import cv2# load imageimg = cv2.imread("gr.png")# convert to HSVhsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # set lower and upper color limitslower_val = (30, 0, 0)upper_val = (65,255,255)# Threshold the HSV image to get only green colors# the mask has white where the original image has greenmask = cv2.inRange(hsv, lower_val, upper_val)# remove noisekernel = np.ones((8,8),np.uint8)mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)# sum each row and each volumn of the imagesumOfCols = np.sum(mask, axis=0)sumOfRows = np.sum(mask, axis=1)# Find the first and last row / column that has a sum value greater than zero, # which means its not all black. Store the found values in variablesfor i in range(len(sumOfCols)): if sumOfCols[i] > 0: x1 = i print('First col: ' + str(i)) breakfor i in range(len(sumOfCols)-1,-1,-1): if sumOfCols[i] > 0: x2 = i print('Last col: ' + str(i)) breakfor i in range(len(sumOfRows)): if sumOfRows[i] > 0: y1 = i print('First row: ' + str(i)) breakfor i in range(len(sumOfRows)-1,-1,-1): if sumOfRows[i] > 0: y2 = i print('Last row: ' + str(i)) break# create a new image based on the found values#roi = img[y1:y2,x1:x2]#show images#cv2.imshow("Roi", roi)# optional: to cut off the extra part at the top:#invert mask, all area's not green become whitemask_inv = cv2.bitwise_not(mask)# search the first and last column top down for a green pixel and cut off at lowest common pointfor i in range(mask_inv.shape[0]): if mask_inv[i,0] == 0 and mask_inv[i,x2] == 0: y1 = i print('First row: ' + str(i)) break# create a new image based on the found valuesroi2 = img[y1:y2,x1:x2]cv2.imshow("Roi2", roi2)cv2.imwrite("img_cropped.jpg", roi2)cv2.waitKey(0)cv2.destroyAllWindows()
12345678_0001
根据您添加的新图像,我假设您不仅希望按照要求剪掉非绿色部分,而且还希望绳索/结周围有一个较小的框架。那是对的吗?如果没有,您应该上传视频并更多地描述裁剪的目的/目标,以便我们更好地为您提供帮助。假设你想要一个只有绳索的裁剪图像,解决方案与之前的答案非常相似。但是,这次绳索的红色和蓝色是使用 HSV 选择的。根据生成的蒙版裁剪图像。如果您希望图像比绳索大一些,您可以添加额外的边距 - 但一定要考虑/检查图像的边缘。注意:下面的代码适用于具有全绿色背景的图像,因此我建议您将其与仅选择绿色区域的解决方案之一结合使用。我对您的所有图像进行了如下测试:我从我的另一个答案中获取了代码,将其放入一个函数中并添加return roi2到最后。此输出被馈送到保存以下代码的第二个函数。所有图像处理成功。结果:代码:import numpy as np import cv2# load imageimg = cv2.imread("image.JPG")# bluelower_val_blue = (110, 0, 0)upper_val_blue = (179,255,155)# redlower_val_red = (0, 0, 150)upper_val_red = (10,255,255)# Threshold the HSV imagemask_blue = cv2.inRange(img, lower_val_blue, upper_val_blue)mask_red = cv2.inRange(img, lower_val_red, upper_val_red)# combine masksmask_total = cv2.bitwise_or(mask_blue,mask_red)# remove noisekernel = np.ones((8,8),np.uint8)mask_total = cv2.morphologyEx(mask_total, cv2.MORPH_CLOSE, kernel)# sum each row and each volumn of the masksumOfCols = np.sum(mask_total, axis=0)sumOfRows = np.sum(mask_total, axis=1)# Find the first and last row / column that has a sum value greater than zero, # which means its not all black. Store the found values in variablesfor i in range(len(sumOfCols)): if sumOfCols[i] > 0: x1 = i print('First col: ' + str(i)) breakfor i in range(len(sumOfCols)-1,-1,-1): if sumOfCols[i] > 0: x2 = i print('Last col: ' + str(i)) breakfor i in range(len(sumOfRows)): if sumOfRows[i] > 0: y1 = i print('First row: ' + str(i)) breakfor i in range(len(sumOfRows)-1,-1,-1): if sumOfRows[i] > 0: y2 = i print('Last row: ' + str(i)) break# create a new image based on the found valuesroi = img[y1:y2,x1:x2]#show imagecv2.imshow("Result", roi)cv2.imshow("Image", img)cv2.waitKey(0)cv2.destroyAllWindows()