简体   繁体   中英

Find box in the image and save as an image cv2

I am new in computer vision, and I want to create a program which helps me to detect box in the image and save as an image.

输入图像

输出图像 1

输出图像 2

and etc... I tried some code but did not get my desired result. here is my code and its output.

import cv2
# Load iamge, grayscale, adaptive threshold
image = cv2.imread('image.jpeg')
result = image.copy()
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,51,9)

# Fill rectangular contours
cnts = cv2.findContours(thresh, 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, (255,255,255), -1)

# Morph open
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=4)

# Draw rectangles
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 3)

cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('image', image)
cv2.waitKey()

output:

代码输出

All you need to do is simply first remove the outermost white area, that is, make it black so that we can detect the boxes without any issues using the cv2.RETR_EXTERNAL flag as they are not touching. Then we'll just extract the boxes one by one.

To remove the outmost area, I have used the point polygon test of the contours. If the point (1, 1) lies inside or on a contour, it is not drawn and every other contour will be drawn on a new image. From this new image, I have read the box contours and extracted them.

import cv2
import numpy as np

img = cv2.imread("2lscp.png", cv2.IMREAD_GRAYSCALE)
ret, img = cv2.threshold(img, 50, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

Contours = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2]

newImg = np.zeros(img.shape, dtype=np.uint8)
for Contour in Contours:
    if cv2.pointPolygonTest(Contour, (1, 1), False) == -1:
        cv2.drawContours(newImg, [Contour], -1, 255, 1)

Contours = cv2.findContours(newImg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
for Contour in Contours:
    [x, y, w, h] = cv2.boundingRect(Contour)

    cv2.imshow("box extracted", img[y:y+h, x:x+w])
    cv2.waitKey(0)

cv2.destroyAllWindows()

This case seems particularly simple because the image is quasi-binary. Detect the contours of the white regions and select those that have an area like 10 to 15% of the whole image. These are the desired boxes. Then fit a rectangle or rotated rectangle.

No need for additional processing.

Here is solution

try this:

import cv2
import numpy as np

#Read input image
img = cv2.imread('hw_data.png')

#convert from BGR to HSV color space
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#apply threshold
thresh = cv2.threshold(gray, 30, 255, cv2.THRESH_BINARY)[1]

# find contours and get one with area about 180*35
# draw all contours in green and accepted ones in red
contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
#area_thresh = 0
min_area = 0.95*180*44
max_area = 1.05*180*44
print(min_area)
print(max_area)
result = img.copy()
i = 1
for c in contours:
#     print(c)
    area = cv2.contourArea(c)
    cv2.drawContours(result, [c], -1, (0, 255, 0), 1)
    
    x,y,w,h = cv2.boundingRect(c)
    # crop region of img using bounding box
    region = result[y:y+h, x:x+w]
    # save region to new image
    print(region.shape,' i ',i)
#     cv2.imwrite("black_region_{0}.png".format(i), region)
    i = i + 1
    if region.shape[0]>70 and region.shape[1]<100:
        cv2.imwrite("black_region_{0}.png".format(i), region)
#         break
#     if area > min_area and area < max_area:
#             cv2.drawContours(result, [c], -1, (0, 0, 255), 1)
#             break

# save result
# cv2.imwrite("box_found.png", result)

# show images
# cv2.imshow("GRAY", gray)
# cv2.imshow("THRESH", thresh)
# cv2.imshow("RESULT", result)
# cv2.waitKey(0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM