本文鏈接:https://blog.csdn.net/ling_xiobai/article/details/79691785
今天使用opencv運行一個腳本,但是出現cv2.cv.BoxPoints()函數有錯,提示’module’ object has no attribute ‘cv’ 的錯誤,找了一些帖,發現最多的解決方法就是說“這是因為opencv3已經沒有了cv,只能重新下載opencv2 ; ”,我就納悶了,有新的版本不用,為什么還要下載舊的版本。有的更是建議“from cv2 import cv as cv”這是開玩笑吧,根本不起作用,根本原因就是版本不支持。但是我只是想用這個函數來找出坐標而已,重新下載一個opencv,感覺好麻煩,最后去stackflow硬是鍛煉了一下英文參考鏈接,偶然發現原來opencv3的版本中只是改了一點,所以:
如果你只是想用這個函數的功能,又不想裝opencv2,那么只需把cv2.cv.BoxPoints()函數改為cv2.boxPoints()。
#順便提一下,版本語法不兼容的錯誤經常會出現,比如python2 vs python3 , opencv2 vs opencv3 ,
也不建議大家要一根筋去把他們的差異背下來,只需要出現問題的時候去網上找就行。
附加:
有時候寫findContours函數時會遇上too many values to unpack (expected 2),也是版本的原因:
cv2.findContours()函數
函數的原型為
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
opencv2返回兩個值:contours,hierarchy。注:opencv3會返回三個值,分別是img, countours, hierarchy
參考文章:https://blog.csdn.net/hjxu2016/article/details/77833336
解析差異:
OpenCV2和OpenCV4中:
findContours這個輪廓提取函數會返回兩個值:
①輪廓的點集(contours)
②各層輪廓的索引(hierarchy)
OpenCV3中:
則會返回三個值:
①處理的圖像(image)
②輪廓的點集(contours)
③各層輪廓的索引(hierarchy)
三、cv2.findContours()相關:
1、參數:
①第一個參數:
尋找輪廓的圖像 |
②第二個參數表示輪廓的檢索模式,有四種:
cv2.RETR_EXTERNAL | 只檢測外輪廓 |
cv2.RETR_LIST | 檢測的輪廓不建立等級關系 |
cv2.RETR_CCOMP | 建立兩個等級的輪廓,上面的一層為外邊界,里面的一層為內孔的邊界信息 |
cv2.RETR_TREE | 建立一個等級樹結構的輪廓 |
③第三個參數method為輪廓的近似辦法:
cv2.CHAIN_APPROX_SIMPLE | 壓縮水平方向,垂直方向,對角線方向的元素,只保留該方向的終點坐標(矩形只需四頂點) |
cv2.CHAIN_APPROX_TC89_L1 | 使用teh-Chinl chain 近似算法 |
CV_CHAIN_APPROX_TC89_KCOS | |
cv2.CHAIN_APPROX_NONE | 存儲所有的輪廓點,相鄰的兩個點的像素位置差不超過1 |
# USAGE # python detect_barcode.py --image images/barcode_01.jpg # import the necessary packages import numpy as np import argparse import cv2 # construct the argument parse and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required = True, help = "path to the image file") args = vars(ap.parse_args()) # load the image and convert it to grayscale image = cv2.imread(args["image"]) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # compute the Scharr gradient magnitude representation of the images # in both the x and y direction gradX = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 1, dy = 0, ksize = -1) gradY = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 0, dy = 1, ksize = -1) # subtract the y-gradient from the x-gradient gradient = cv2.subtract(gradX, gradY) gradient = cv2.convertScaleAbs(gradient) # blur and threshold the image blurred = cv2.blur(gradient, (9, 9)) (_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY) # construct a closing kernel and apply it to the thresholded image kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7)) closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) # perform a series of erosions and dilations closed = cv2.erode(closed, None, iterations = 4) closed = cv2.dilate(closed, None, iterations = 4) # find the contours in the thresholded image, then sort the contours # by their area, keeping only the largest one (kkk, cnts, lll) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) c = sorted(cnts, key = cv2.contourArea, reverse = True)[0] # compute the rotated bounding box of the largest contour rect = cv2.minAreaRect(c) box = np.int0(cv2.boxPoints(rect)) # draw a bounding box arounded the detected barcode and display the # image cv2.drawContours(image, [box], -1, (0, 255, 0), 3) cv2.imshow("Image", image) cv2.waitKey(0)