Opencv 和 python 获取文档正确的轮廓并在图像上绘制
Opencv and python get document correct contur and draw on image
Using opencv with python 这里是文档结构的输出
我正在使用 opencv_python-4.2.0.34
左下角不像其他角那样尖锐。如何做对? (自动编辑左下角以使其看起来清晰,其他出现时不显示)
这里是绘制等高线的代码:
img = cv2.imread(imagePath)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
invGamma = 1.0 / 0.3
table = np.array([((i / 255.0) ** invGamma) * 255
for i in np.arange(0, 256)]).astype("uint8")
# apply gamma correction using the lookup table
gray = cv2.LUT(gray, table)
ret, thresh1 = cv2.threshold(gray, 80, 255, cv2.THRESH_BINARY)
contours, hierachy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# except:
# print('exception occurred')
def biggestRectangle(conts):
biggest = None
max_area = 0
indexReturn = -1
for index in range(len(conts)):
i = conts[index]
area = cv2.contourArea(i)
if area > 100:
peri = cv2.arcLength(i, True)
approx = cv2.approxPolyDP(i, 0.1 * peri, True)
if area > max_area and len(approx) == 4:
biggest = approx
max_area = area
indexReturn = index
return indexReturn
indexReturn = biggestRectangle(contours)
hull = cv2.convexHull(contours[indexReturn])
print(indexReturn)
print(contours[indexReturn])
print(hull)
# copyImg = img.copy()
cv2.imwrite(os.path.join('path_to_save', imageName),
cv2.drawContours(img, [hull], 0, (0, 255, 0), 3))
如何使它正确。我尝试了另一种方法:
x, y, w, h = cv2.boundingRect(hull)
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
newImageName = imageName.split('.')
newImageName = newImageName[0] + '_rect.' + newImageName[1]
print(newImageName)
cv2.imwrite(os.path.join('path_to_save', newImageName), img)
但它给了我这个(蓝色轮廓):
这也是错误的。如何纠正?
既然你知道你感兴趣的轮廓是一张纸,也许你可以使用更系统的方法使用OpenCV的cv2.minAreaRect
找到最大的旋转矩形(link). It will return the center, size, and rotation of the rectangle that most tightly encloses your contour. Since your image has a pretty difficult background, I had to apply a few more processing steps using OpenCV's morphologyEx function在抓取之前轮廓,但是这段代码我可以看到更好的输出(如下所示)。
# first, do some processing
kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (27, 27))
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (13, 13))
thresh1 = cv2.morphologyEx(thresh1, cv2.MORPH_ERODE, kernel1)
thresh1 = cv2.morphologyEx(thresh1, cv2.MORPH_DILATE, kernel2)
# find all contours
contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
# Find the largest ('max' using the key of the contour area)
biggest_contour = max(contours, key=cv2.contourArea)
# Calculate the minimum enclosing rectangle: format ((x, y), (length, width), angle)
rectangle = cv2.minAreaRect(biggest_contour)
# conver the minAreaRect output to points
pts = cv2.boxPoints(rectangle)
# contours must be of shape (n, 1, 2) and dtype integer
pts = pts.reshape(-1, 1, 2)
pts = pts.astype(int)
# draw contours and display
cv2.drawContours(img, [pts], -1, (255, 0, 0), 2)
cv2.imshow('img', img)
k = cv2.waitKey(0)
输出:
Using opencv with python 这里是文档结构的输出
我正在使用 opencv_python-4.2.0.34
左下角不像其他角那样尖锐。如何做对? (自动编辑左下角以使其看起来清晰,其他出现时不显示)
这里是绘制等高线的代码:
img = cv2.imread(imagePath)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
invGamma = 1.0 / 0.3
table = np.array([((i / 255.0) ** invGamma) * 255
for i in np.arange(0, 256)]).astype("uint8")
# apply gamma correction using the lookup table
gray = cv2.LUT(gray, table)
ret, thresh1 = cv2.threshold(gray, 80, 255, cv2.THRESH_BINARY)
contours, hierachy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# except:
# print('exception occurred')
def biggestRectangle(conts):
biggest = None
max_area = 0
indexReturn = -1
for index in range(len(conts)):
i = conts[index]
area = cv2.contourArea(i)
if area > 100:
peri = cv2.arcLength(i, True)
approx = cv2.approxPolyDP(i, 0.1 * peri, True)
if area > max_area and len(approx) == 4:
biggest = approx
max_area = area
indexReturn = index
return indexReturn
indexReturn = biggestRectangle(contours)
hull = cv2.convexHull(contours[indexReturn])
print(indexReturn)
print(contours[indexReturn])
print(hull)
# copyImg = img.copy()
cv2.imwrite(os.path.join('path_to_save', imageName),
cv2.drawContours(img, [hull], 0, (0, 255, 0), 3))
如何使它正确。我尝试了另一种方法:
x, y, w, h = cv2.boundingRect(hull)
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
newImageName = imageName.split('.')
newImageName = newImageName[0] + '_rect.' + newImageName[1]
print(newImageName)
cv2.imwrite(os.path.join('path_to_save', newImageName), img)
但它给了我这个(蓝色轮廓):
这也是错误的。如何纠正?
既然你知道你感兴趣的轮廓是一张纸,也许你可以使用更系统的方法使用OpenCV的cv2.minAreaRect
找到最大的旋转矩形(link). It will return the center, size, and rotation of the rectangle that most tightly encloses your contour. Since your image has a pretty difficult background, I had to apply a few more processing steps using OpenCV's morphologyEx function在抓取之前轮廓,但是这段代码我可以看到更好的输出(如下所示)。
# first, do some processing
kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (27, 27))
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (13, 13))
thresh1 = cv2.morphologyEx(thresh1, cv2.MORPH_ERODE, kernel1)
thresh1 = cv2.morphologyEx(thresh1, cv2.MORPH_DILATE, kernel2)
# find all contours
contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
# Find the largest ('max' using the key of the contour area)
biggest_contour = max(contours, key=cv2.contourArea)
# Calculate the minimum enclosing rectangle: format ((x, y), (length, width), angle)
rectangle = cv2.minAreaRect(biggest_contour)
# conver the minAreaRect output to points
pts = cv2.boxPoints(rectangle)
# contours must be of shape (n, 1, 2) and dtype integer
pts = pts.reshape(-1, 1, 2)
pts = pts.astype(int)
# draw contours and display
cv2.drawContours(img, [pts], -1, (255, 0, 0), 2)
cv2.imshow('img', img)
k = cv2.waitKey(0)
输出: