如何在不同的 OpenCV 版本中使用 `cv2.findContours`?
How to use `cv2.findContours` in different OpenCV versions?
我正在尝试将 OpenCV 与 Python 结合使用,以便检测来自 Raspberry Pi 摄像头的实时视频馈送中的方块。但是,下面代码中的 cv2.GaussianBlur
和 cv2.Canny
函数会导致以下错误:"TypeError: numpy.ndarray' object is not callable".
我似乎无法解决这个错误。任何帮助表示赞赏。
import cv2
# load the video
camera = cv2.VideoCapture(0)
# keep looping
while True:
# grab the current frame and initialize the status text
(grabbed, frame) = camera.read()
status = "No Targets"
# check to see if we have reached the end of the
# video
if not grabbed:
break
# convert the frame to grayscale, blur it, and detect edges
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)
edged = cv2.Canny(blurred, 50, 150)
# find contours in the edge map
(cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
# loop over the contours
for c in cnts:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.01 * peri, True)
# ensure that the approximated contour is "roughly" rectangular
if len(approx) >= 4 and len(approx) <= 6:
# compute the bounding box of the approximated contour and
# use the bounding box to compute the aspect ratio
(x, y, w, h) = cv2.boundingRect(approx)
aspectRatio = w / float(h)
# compute the solidity of the original contour
area = cv2.contourArea(c)
hullArea = cv2.contourArea(cv2.convexHull(c))
solidity = area / float(hullArea)
# compute whether or not the width and height, solidity, and
# aspect ratio of the contour falls within appropriate bounds
keepDims = w > 25 and h > 25
keepSolidity = solidity > 0.9
keepAspectRatio = aspectRatio >= 0.8 and aspectRatio <= 1.2
# ensure that the contour passes all our tests
if keepDims and keepSolidity and keepAspectRatio:
# draw an outline around the target and update the status
# text
cv2.drawContours(frame, [approx], -1, (0, 0, 255), 4)
status = "Target(s) Acquired"
# draw the status text on the frame
cv2.putText(frame, status, (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255), 2)
# show the frame and record if a key is pressed
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# if the 'q' key is pressed, stop the loop
if key == ord("q"):
break
# cleanup the camera and close any open windows
camera.release()
cv2.destroyAllWindows()
使用 2.x 、3.x、4.x 的替代方法是:
cnts, hiers = cv2.findContours(...)[-2:]
通知:
cv2.findContours
自 OpenCV 3.x
以来发生了变化,但在 OpenCV 4.0
中又变回来了!!!
在 OpenCV 3.4 中:
findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> image, contours, hierarchy
在 OpenCV 4.0 中:
findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy
这是另一种存储从 cv2.findContours()
返回的所有元组的方法,与 system/environment 中安装的 OpenCV 版本无关:
首先,获取安装的 OpenCV 版本(我们不希望整个版本只是主编号 3 或 4 ) :
import cv2
major_number = cv2.__version__[0]
根据版本,将执行以下两个语句之一并填充相应的变量:
if major_number == '4':
contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
elif major_number == '3':
img, contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
在任一场景中从函数返回的轮廓将存储在 contours
。
3.X.X
版本:documentation
4.X.X
版本:documentation
这是我从@nathancy 那里学到的一种自动方法。 if 三元 if 测试,确定有多少个 return 值并为轮廓选择合适的值。
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
我正在尝试将 OpenCV 与 Python 结合使用,以便检测来自 Raspberry Pi 摄像头的实时视频馈送中的方块。但是,下面代码中的 cv2.GaussianBlur
和 cv2.Canny
函数会导致以下错误:"TypeError: numpy.ndarray' object is not callable".
我似乎无法解决这个错误。任何帮助表示赞赏。
import cv2
# load the video
camera = cv2.VideoCapture(0)
# keep looping
while True:
# grab the current frame and initialize the status text
(grabbed, frame) = camera.read()
status = "No Targets"
# check to see if we have reached the end of the
# video
if not grabbed:
break
# convert the frame to grayscale, blur it, and detect edges
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)
edged = cv2.Canny(blurred, 50, 150)
# find contours in the edge map
(cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
# loop over the contours
for c in cnts:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.01 * peri, True)
# ensure that the approximated contour is "roughly" rectangular
if len(approx) >= 4 and len(approx) <= 6:
# compute the bounding box of the approximated contour and
# use the bounding box to compute the aspect ratio
(x, y, w, h) = cv2.boundingRect(approx)
aspectRatio = w / float(h)
# compute the solidity of the original contour
area = cv2.contourArea(c)
hullArea = cv2.contourArea(cv2.convexHull(c))
solidity = area / float(hullArea)
# compute whether or not the width and height, solidity, and
# aspect ratio of the contour falls within appropriate bounds
keepDims = w > 25 and h > 25
keepSolidity = solidity > 0.9
keepAspectRatio = aspectRatio >= 0.8 and aspectRatio <= 1.2
# ensure that the contour passes all our tests
if keepDims and keepSolidity and keepAspectRatio:
# draw an outline around the target and update the status
# text
cv2.drawContours(frame, [approx], -1, (0, 0, 255), 4)
status = "Target(s) Acquired"
# draw the status text on the frame
cv2.putText(frame, status, (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255), 2)
# show the frame and record if a key is pressed
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# if the 'q' key is pressed, stop the loop
if key == ord("q"):
break
# cleanup the camera and close any open windows
camera.release()
cv2.destroyAllWindows()
使用 2.x 、3.x、4.x 的替代方法是:
cnts, hiers = cv2.findContours(...)[-2:]
通知:
cv2.findContours
自 OpenCV 3.x
以来发生了变化,但在 OpenCV 4.0
中又变回来了!!!
在 OpenCV 3.4 中:
findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> image, contours, hierarchy
在 OpenCV 4.0 中:
findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy
这是另一种存储从 cv2.findContours()
返回的所有元组的方法,与 system/environment 中安装的 OpenCV 版本无关:
首先,获取安装的 OpenCV 版本(我们不希望整个版本只是主编号 3 或 4 ) :
import cv2
major_number = cv2.__version__[0]
根据版本,将执行以下两个语句之一并填充相应的变量:
if major_number == '4':
contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
elif major_number == '3':
img, contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
在任一场景中从函数返回的轮廓将存储在 contours
。
3.X.X
版本:documentation
4.X.X
版本:documentation
这是我从@nathancy 那里学到的一种自动方法。 if 三元 if 测试,确定有多少个 return 值并为轮廓选择合适的值。
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]