我想裁剪影像以僅提取文本部分。有成千上萬個不同大小的,所以我不能硬編碼坐標。我正在嘗試洗掉左側和底部不需要的線條。我怎樣才能做到這一點?
| 原來的 | 預期的 |
|---|---|
![]() |
![]() |
uj5u.com熱心網友回復:
這是一個簡單的方法:
獲取二值影像。

擴張以組合成單個輪廓
->檢測到的 ROI 以綠色提取3 4 

結果
代碼
import cv2 import numpy as np # Load image, grayscale, Gaussian blur, Otsu's threshold image = cv2.imread('1.png') original = image.copy() gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (3, 3), 0) thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1] # Remove horizontal lines horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1)) detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=1) cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] for c in cnts: cv2.drawContours(thresh, [c], -1, 0, -1) # Dilate to merge into a single contour vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,30)) dilate = cv2.dilate(thresh, vertical_kernel, iterations=3) # Find contours, sort for largest contour and extract ROI cnts, _ = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:] cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:-1] for c in cnts: x,y,w,h = cv2.boundingRect(c) cv2.rectangle(image, (x, y), (x w, y h), (36,255,12), 4) ROI = original[y:y h, x:x w] break cv2.imshow('image', image) cv2.imshow('dilate', dilate) cv2.imshow('thresh', thresh) cv2.imshow('ROI', ROI) cv2.waitKey()uj5u.com熱心網友回復:
通過查找影像中的所有非零點來確定最小跨度邊界框。最后,使用此邊界框裁剪影像。在這里查找輪廓既耗時又不必要,尤其是因為您的文本是軸對齊的。您可以通過組合
cv2.findNonZero和來實作您的目標cv2.boundingRect。希望這會奏效!:
import numpy as np import cv2 img = cv2.imread(r"W430Q.png") # Read in the image and convert to grayscale img = img[:-20, :-20] # Perform pre-cropping gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = 255*(gray < 50).astype(np.uint8) # To invert the text to white gray = cv2.morphologyEx(gray, cv2.MORPH_OPEN, np.ones( (2, 2), dtype=np.uint8)) # Perform noise filtering coords = cv2.findNonZero(gray) # Find all non-zero points (text) x, y, w, h = cv2.boundingRect(coords) # Find minimum spanning bounding box # Crop the image - note we do this on the original image rect = img[y:y h, x:x w] cv2.imshow("Cropped", rect) # Show it cv2.waitKey(0) cv2.destroyAllWindows()在第四行代碼的上面代碼中,我將閾值設定為低于 50 以使深色文本變為白色。但是,因為這會輸出二進制影像,所以我轉換為
uint8,然后按 255 縮放。文本被有效地反轉。然后,使用
cv2.findNonZero,我們發現該影像的所有非零位置。然后我們將其傳遞給cv2.boundingRect,它回傳邊界框的左上角,以及它的寬度和高度。最后,我們可以利用它來裁剪影像。這是在原始影像上完成的,而不是倒置版本。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/480652.html


