问题
I have a binary image and I want to find contours, to fit the biggest one into a new image with the size of the contour as if a rectangle was around it. In other words, to fit the contour into a new image with lower size.
The find contours routine is finding a rectangle for the whole image, and I don't need it. I look a contour of dimension (width - 1, height - 1) and skip it.
I want to remove biggest rectangle and then fit the 2nd biggest rectangle into a new image. That biggest rectangle will make the limits of the new image. Then I want to draw contours into a new white image.
I just don't know enough about OpenCV and the best way of doing this.
h = img.shape[0]
w = img.shape[1]
ret, img = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)
# are these the best find contours params?
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# paint a new image white
img = np.zeros((384, 640, 1), np.uint8)
img[:-1] = 255
# resize the contours
for i in range(0, len(contours)):
for j in range(0, len(contours[i])):
for k in range(0, len(contours[i][j])):
if contours[i][j][k][1] != h - 1 or contours[i][j][k][0] != w -1:
contours[i][j][k][1] = 384 * contours[i][j][k][1] / h
contours[i][j][k][0] = 640 * contours[i][j][k][0] / w
I can't find a way of finding the rectangle for the whole document. The biggest rectangle is image width * height, but in the 2nd one, only black pixels are visible.
回答1:
In the comments you state that you want the black pixels as the bounds of the image. In that case you can use the method below. It loads the image as grayscale and then inverts it. So the white in the original image is now black (value: 0) and the black becomes white (value: 255). Next all rows and columns are summed up. The first and last rows/columns that have a sum that is greater than zero are the bounds of the black pixels in the original image. YOu can use these values to slice a new image.
Result:
Code:
import cv2
import numpy as np
# load the image as grayscale
img = cv2.imread('mQTiR.png',0)
#invert the image
img_inv = cv2.bitwise_not(img)
# sum each row and each column of the inverted image
sumOfCols = np.sum(img_inv, axis=0)
sumOfRows = np.sum(img_inv, axis=1)
# get the indexes of the rows/cols that are nonzero (=black in scan)
nonzeroX = np.nonzero(sumOfCols)[0]
nonzeroY = np.nonzero(sumOfRows)[0]
# get the first and last indexes, these are the bounds of the roi
minY = nonzeroY[0]
maxY = nonzeroY[-1]
minX = nonzeroX[0]
maxX = nonzeroX[-1]
#create subimage
subimage = img[minY:maxY,minX:maxX]
#display subimage
cv2.imshow('Result',subimage)
cv2.waitKey(0)
cv2.destroyAllWindows()
来源:https://stackoverflow.com/questions/57127734/i-cant-find-a-way-to-fit-contour-on-new-image-zero-point