Python 如何使用OpenCV根据特定标准裁剪图像?

Python 如何使用OpenCV根据特定标准裁剪图像?,python,opencv,image-processing,crop,Python,Opencv,Image Processing,Crop,我想使用python的OpenCV库裁剪下面的图像。感兴趣的区域位于顶部和底部的曲线内,以及侧面的曲线内。问题是每幅图像都略有不同。这意味着我需要为感兴趣的区域自动裁剪。我想顶部和侧面会很容易,因为你可以把它裁剪10像素左右。但是,如果线条不直,如何裁剪出图像的下半部分?我已经包括了这个示例图像。下面的图像以粉红色突出显示我感兴趣保留的图像区域 这里有一种使用Python/OpenCV的方法 读取输入 获取中心点(假设它位于所需区域内) 将图像转换为灰度 泛光填充灰色图像并将背景设置为黑色

我想使用python的OpenCV库裁剪下面的图像。感兴趣的区域位于顶部和底部的曲线内,以及侧面的曲线内。问题是每幅图像都略有不同。这意味着我需要为感兴趣的区域自动裁剪。我想顶部和侧面会很容易,因为你可以把它裁剪10像素左右。但是,如果线条不直,如何裁剪出图像的下半部分?我已经包括了这个示例图像。下面的图像以粉红色突出显示我感兴趣保留的图像区域


这里有一种使用Python/OpenCV的方法

  • 读取输入
  • 获取中心点(假设它位于所需区域内)
  • 将图像转换为灰度
  • 泛光填充灰色图像并将背景设置为黑色
  • 获取最大轮廓及其边界框
  • 绘制黑色背景上填充的最大轮廓作为遮罩
  • 将遮罩应用于输入图像
  • 裁剪遮罩的输入图像
输入:


结果:

绘制等高线的结果:

欢迎来到StackOverflow。本网站不作为一般问题解决门户。社区将与您合作,以获得一个有效的解决方案,但您应该分享一些代码,说明您已经完成了哪些工作,哪些工作还没有完成。阅读如何创建一个最小的、可重复的示例(),以及如何提出一个好问题()?我建议你研究一下粉红色区域的洪水填充和等高线。你好,我已经尝试使用我自己的基本代码,但它只是不起作用。我尝试过以下方法:img=img[30:-30,30:-30,:],但它只从图像的每一端刮去30个像素。我正在寻找一种更复杂的方法来删除图像的底部轮廓。我建议您查看cv2.floodfill和cv2.findContours,以获得粉红色区域的外部轮廓。创建该区域的遮罩,并将该区域复制到新的黑色图像中,该图像的大小与该轮廓的边界框的大小相同。
import cv2
import numpy as np

# load image and get dimensions
img = cv2.imread("odd_region.png")
hh, ww, cc = img.shape

# compute center of image (as integer)
wc = ww//2
hc = hh//2

# create grayscale copy of input as basis of mask
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# create zeros mask 2 pixels larger in each dimension
zeros = np.zeros([hh + 2, ww + 2], np.uint8)

# do floodfill at center of image as seed point
ffimg = cv2.floodFill(gray, zeros, (wc,hc), (255), (0), (0), flags=8)[1]

# set rest of ffimg to black
ffimg[ffimg!=255] = 0

# get contours, find largest and its bounding box 
contours = cv2.findContours(ffimg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
area_thresh = 0
for cntr in contours:
    area = cv2.contourArea(cntr)
    if area > area_thresh:
        area = area_thresh
        outer_contour = cntr
        x,y,w,h = cv2.boundingRect(outer_contour)

# draw the filled contour on a black image
mask = np.full([hh,ww,cc], (0,0,0), np.uint8)
cv2.drawContours(mask,[outer_contour],0,(255,255,255),thickness=cv2.FILLED)

# mask the input
masked_img = img.copy()
masked_img[mask == 0] = 0
#masked_img[mask != 0] = img[mask != 0]

# crop the bounding box region of the masked img
result = masked_img[y:y+h, x:x+w]

# draw the contour outline on a copy of result
result_outline = result.copy()
cv2.drawContours(result_outline,[outer_contour],0,(0,0,255),thickness=1,offset=(-x,-y))


# display it
cv2.imshow("img", img)
cv2.imshow("ffimg", ffimg)
cv2.imshow("mask", mask)
cv2.imshow("masked_img", masked_img)
cv2.imshow("result", result)
cv2.imshow("result_outline", result_outline)
cv2.waitKey(0)
cv2.destroyAllWindows()

# write result to disk
cv2.imwrite("odd_region_cropped.png", result)
cv2.imwrite("odd_region_cropped_outline.png", result_outline)