所以我试图从这张图片Picture for reference中提取盒子。根据{{3}},RETR_EXTERNAL
应该返回“仅极端外部标志”。他们的话不是我的。根据他们的返回,仅返回每个家庭中的长子父母。因此,我假设使用RETR_EXTERNAL
将提取参考图像中的表格和按钮。但是当我使用RETR_EXTERNAL
时,它仅生成参考图像(我首先链接到的图像)作为输出。好像整个图像周围都有一个看不见的盒子。
感谢您的帮助
以下是您需要的代码:
import cv2
import numpy as np
import argparse
import imutils
import nn
from PIL import Image, ImageFont, ImageDraw, ImageEnhance
def sort_contours(cnts, method="left-to-right"):
# initialize the reverse flag and sort index
reverse = False
i = 0
# handle if we need to sort in reverse
if method == "right-to-left" or method == "bottom-to-top":
reverse = True
# handle if we are sorting against the y-coordinate rather than
# the x-coordinate of the bounding box
if method == "top-to-bottom" or method == "bottom-to-top":
i = 1
# construct the list of bounding boxes and sort them from top to
# bottom
boundingBoxes = [cv2.boundingRect(c) for c in cnts]
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda b:b[1][i], reverse=reverse))
# return the list of sorted contours and bounding boxes
return (cnts, boundingBoxes)
def box_extraction(img_for_box_extraction_path, cropped_dir_path):
# Read the image
img = cv2.imread('41.jpg', 0)
(thresh, img_bin) = cv2.threshold(img, 128, 255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)
#print len(img_bin)
img_bin =255-img_bin
cv2.imwrite("Image_bin.jpg",img_bin)
# Defining a kernel length
kernel_length = np.array(img).shape[1]/80
#print kernel_length
verticle_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, kernel_length))
# A horizontal kernel of (kernel_length X 1), which will help to detect all the horizontal line from the image.
hori_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_length, 1))
# A kernel of (3 X 3) ones.
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# Morphological operation to detect vertical lines from an image
img_temp1 = cv2.erode(img_bin, verticle_kernel, iterations=7)
verticle_lines_img = cv2.dilate(img_temp1, verticle_kernel, iterations=7)
cv2.imwrite("verticle_lines.jpg",verticle_lines_img)
# Morphological operation to detect horizontal lines from an image
img_temp2 = cv2.erode(img_bin, hori_kernel, iterations=7)
horizontal_lines_img = cv2.dilate(img_temp2, hori_kernel, iterations=7)
cv2.imwrite("horizontal_lines.jpg",horizontal_lines_img)
# Weighting parameters, this will decide the quantity of an image to be added to make a new image.
alpha = 0.6
beta = 1.0 - alpha
# This function helps to add two image with specific weight parameter to get a third image as summation of two image.
img_final_bin = cv2.addWeighted(verticle_lines_img, alpha, horizontal_lines_img, beta, 0.0)
img_final_bin = cv2.erode(~img_final_bin, kernel, iterations=2)
(thresh, img_final_bin) = cv2.threshold(img_final_bin, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# Find contours for image, which will detect all the boxes
im2, contours, hierarchy = cv2.findContours(img_final_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Sort all the contours by top to bottom.
#(contours, boundingBoxes) = sort_contours(contours, method="top-to-bottom")
答案 0 :(得分:0)
在OpenCV中,找到轮廓就像从黑色背景中找到白色对象。因此请记住,要找到的对象应该是白色,背景应该是黑色。
findContours首先搜索白色物体。因此,最外面的轮廓是白色背景。您可以通过在阈值设置时使用img = cv2.bitwise_not(img)
或使用cv2.THRESH_BINARY_INV
来反转图像来轻松解决此问题:
结果:
示例代码:
import numpy as np
import cv2
#load the image:
img = cv2.imread("box.jpg")
# create grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# threshold image to remove noise and create an inverted mask
ret,mask = cv2.threshold(gray,230,255,cv2.THRESH_BINARY_INV)
#Find contours (external only):
im, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#draw contours on original image
cv2.drawContours(img, contours, -1, (0,0,255), thickness=2)
# show image
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意:您还可以将图像加载为灰度图像,并跳过创建图像的步骤,但是我在这里使用了它,因此可以绘制更多明显的红色框。
答案 1 :(得分:0)
import numpy as np
import cv2
img = cv2.imread("image_1.jpg")
## create grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
## threshold image to remove noise and create an inverted mask with with OTSU
mask = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
## Find contours (external only):
## Since the cv2.findContours has been updated to return only 2 parameters
contours, hierarchy= cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
## draw contours on original image
cv2.drawContours(img, contours, -1, (255,0,0), thickness=2)
## show image
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()