Skip to content

Instantly share code, notes, and snippets.

@bigsnarfdude
Last active May 19, 2022 12:18
Show Gist options
  • Save bigsnarfdude/d811e31ee17495f82f10db12651ae82d to your computer and use it in GitHub Desktop.
Save bigsnarfdude/d811e31ee17495f82f10db12651ae82d to your computer and use it in GitHub Desktop.
[boundingBox] opencv example python - Contours – bounding box, minimum area rectangle, and minimum enclosing circle
import cv2
import numpy as np
# read and scale down image
# wget https://bigsnarf.files.wordpress.com/2017/05/hammer.png #black and white
# wget https://i1.wp.com/images.hgmsites.net/hug/2011-volvo-s60_100323431_h.jpg
img = cv2.pyrDown(cv2.imread('2011-volvo-s60_100323431_h.jpg', cv2.IMREAD_UNCHANGED))
# threshold image
ret, threshed_img = cv2.threshold(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),
127, 255, cv2.THRESH_BINARY)
# find contours and get the external one
contours, hier = cv2.findContours(threshed_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#image, contours, hier = cv2.findContours(threshed_img, cv2.RETR_TREE,
# cv2.CHAIN_APPROX_SIMPLE)
# with each contour, draw boundingRect in green
# a minAreaRect in red and
# a minEnclosingCircle in blue
for c in contours:
# get the bounding rect
x, y, w, h = cv2.boundingRect(c)
# draw a green rectangle to visualize the bounding rect
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
# get the min area rect
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
# convert all coordinates floating point values to int
box = np.int0(box)
# draw a red 'nghien' rectangle
cv2.drawContours(img, [box], 0, (0, 0, 255))
# finally, get the min enclosing circle
(x, y), radius = cv2.minEnclosingCircle(c)
# convert all values to int
center = (int(x), int(y))
radius = int(radius)
# and draw the circle in blue
img = cv2.circle(img, center, radius, (255, 0, 0), 2)
print(len(contours))
cv2.drawContours(img, contours, -1, (255, 255, 0), 1)
cv2.imshow("contours", img)
cv2.imshow("contours", img)
while True:
key = cv2.waitKey(1)
if key == 27: #ESC key to break
break
cv2.destroyAllWindows()
@hoai97nam
Copy link

thank you very muchhhh

@hasnainmamdani
Copy link

I get the following error when using the provided hammer.png image:
`---------------------------------------------------------------------------
error Traceback (most recent call last)
in
3
4 # threshold image
----> 5 ret, threshed_img = cv2.threshold(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)
6 # find contours and get the external one
7 image, contours, hier = cv2.findContours(threshed_img, cv2.RETR_TREE,

error: OpenCV(3.4.2) /Users/travis/build/skvark/opencv-python/opencv/modules/imgproc/src/color.hpp:253: error: (-215:Assertion failed) VScn::contains(scn) && VDcn::contains(dcn) && VDepth::contains(depth) in function 'CvtHelper'
`

Which version of opencv are you using?

@mali30
Copy link

mali30 commented Jun 5, 2019

I am having an issue with line 49. Has anyone resolved this?

@bigsnarfdude
Copy link
Author

latest revision - works/tested with python 3.7.1 and open CV 4.1.0

@Mythili-pixel
Copy link

import cv2
import numpy as np
image = cv2.imread('d.jpg',-1)
paper = cv2.resize(image,(500,500))
ret, thresh_gray = cv2.threshold(cv2.cvtColor(paper, cv2.COLOR_BGR2GRAY),
200, 255, cv2.THRESH_BINARY)
image, contours, hier = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for c in contours:
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
# convert all coordinates floating point values to int
box = np.int0(box)
# draw a green 'nghien' rectangle
cv2.drawContours(paper, [box], 0, (0, 255, 0),1)

cv2.imshow('paper', paper)
cv2.imwrite('paper.jpg',paper)

I tried the above code for zebra line detection in an image.It shows output like this.
output.By I need to detect the entire block of zebra crossing .how is to be done?

@Hungprovp
Copy link

Hungprovp commented Jul 14, 2021

hi i was using the code to get a bounding box over shaded objects in a picture.for eg, in the pic included, the car is shaded in red and i'd just like the bounding box to be over the car. however with this code the bounding box is generated over everything. how do i tweak it to get what i want, which is just a bounding box over the objects in the pic that is shaded?.
bboxwrong

Tôi nghĩ rằng bạn thử so sánh các diện tích các đường bao đã thu được trên ảnh:
Đây là mã của tôi:
def get_contours(img_read_img, area_min_thresh=AREA):
img_gray = cv2.cvtColor(img_read_img, cv2.COLOR_BGR2GRAY)
invert_img = cv2.bitwise_not(img_gray)
retval, im_bw = cv2.threshold(invert_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, hier = cv2.findContours(im_bw, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contours = list(filter(lambda x: cv2.contourArea(x) > area_min_thresh, contours))
# img_contours = np.zeros(img_read_img.shape)
# cv2.drawContours(img_contours, contours, -1, (0, 255, 0), 3)
max_area = cv2.contourArea(contours[0])
max_id = 0
for i, c in enumerate(contours):
area = cv2.contourArea(c)
if area > max_area:
max_area = area
max_id = i
max_contours = contours[max_id]
cv2.drawContours(img_read_img, [max_contours], -1, (0, 0, 255), 2)
# cv2.imshow("contour", img_read_img)
# cv2.waitKey(0)
return img_read_img

@anamtaamin
Copy link

Can it work for 2 page PDF?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment