Tác phẩm sau đây cho ví dụ cụ thể của bạn, mặc dù nó có thể cần tinh chỉnh cho phạm vi hình ảnh rộng hơn.
import numpy as np
import cv2
image_src = cv2.imread("input.png")
gray = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)
ret, gray = cv2.threshold(gray, 250,255,0)
image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
largest_area = sorted(contours, key=cv2.contourArea)[-1]
mask = np.zeros(image_src.shape, np.uint8)
cv2.drawContours(mask, [largest_area], 0, (255,255,255,255), -1)
dst = cv2.bitwise_and(image_src, mask)
mask = 255 - mask
roi = cv2.add(dst, mask)
roi_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
ret, gray = cv2.threshold(roi_gray, 250,255,0)
image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
max_x = 0
max_y = 0
min_x = image_src.shape[1]
min_y = image_src.shape[0]
for c in contours:
if 150 < cv2.contourArea(c) < 100000:
x, y, w, h = cv2.boundingRect(c)
min_x = min(x, min_x)
min_y = min(y, min_y)
max_x = max(x+w, max_x)
max_y = max(y+h, max_y)
roi = roi[min_y:max_y, min_x:max_x]
cv2.imwrite("roi.png", roi)
Đem lại cho bạn các loại vật liệu làm hình ảnh đầu ra:
Và ...
Mã này hoạt động bằng cách đầu tiên định vị khu vực đường viền lớn nhất. Từ đây một mặt nạ được tạo ra được sử dụng để đầu tiên chỉ chọn khu vực bên trong, tức là văn bản. Nghịch đảo của mặt nạ sau đó được thêm vào hình ảnh để chuyển đổi khu vực bên ngoài mặt nạ thành màu trắng.
Đường viền cuối cùng được tìm thấy lần nữa cho hình ảnh mới này. Bất kỳ khu vực đường viền nào bên ngoài phạm vi kích thước phù hợp đều bị loại bỏ (điều này được sử dụng để bỏ qua bất kỳ khu vực tiếng ồn nhỏ nào), và một đường cong giới hạn được tìm thấy cho mỗi vùng. Với mỗi hình chữ nhật này, đường biên giới hạn outer
được tính toán cho tất cả các đường bao còn lại và một cây trồng được thực hiện bằng cách sử dụng các giá trị này để cung cấp cho hình ảnh cuối cùng.
Cập nhật - Để có được phần còn lại của hình ảnh, ví dụ: với diện tích trên bị loại bỏ, sau đây có thể được sử dụng:
image_src = cv2.imread("input.png")
gray = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)
ret, gray = cv2.threshold(gray, 10, 255,0)
image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
largest_area = sorted(contours, key=cv2.contourArea)[-1]
mask = np.zeros(image_src.shape, np.uint8)
cv2.drawContours(mask, [largest_area], 0, (255,255,255,255), -1)
image_remainder = cv2.bitwise_and(image_src, 255 - mask)
cv2.imwrite("remainder.png", image_remainder)
với cử tri người đã nói câu hỏi là quá rộng. Vui lòng cho tôi biết cách thu hẹp thêm. Tôi không nghĩ rằng câu hỏi là rộng .. – Anthony
Bạn cần phải làm một số thresholding thích ứng, và mở và đóng hoạt động. http://docs.opencv.org/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html Bạn cũng có thể làm xói mòn hoặc giãn nở tùy chỉnh (điều cơ bản là những hoạt động mở và đóng hoạt động). –
Đây có phải là hình ảnh đầu vào không? Hoặc kết quả từ một số loại thresholding? – ZdaR