OpenCV檢測輪廓極點(Python C++)
阿新 • • 發佈:2020-08-16
今天分享一個OpenCV檢測輪廓極點例項,原圖如下,我們需要檢測出地圖中最大輪廓的上下左右四個極點,並進行標註顯示。
第一步:閾值處理分割出地圖輪廓
第二步:輪廓篩選,找到我們需要的輪廓
第三步:計算對應輪廓的極點座標並標註
Python OpenCV原始碼與效果圖如下:
import numpy as np import cv2 from PIL import Image, ImageDraw, ImageFont font = cv2.FONT_HERSHEY_SIMPLEX def putText_Chinese(img, text, pt, textColor=(0, 255, 0), textSize=20): left, top = pt[0], pt[1] if (isinstance(img, np.ndarray)): #判斷是否OpenCV圖片型別 img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) draw = ImageDraw.Draw(img) fontText = ImageFont.truetype("simhei.ttf", textSize, encoding="utf-8") draw.text((left, top), text, textColor, font=fontText) return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR) img = cv2.imread('2.jpg') cv2.imshow('src',img) temp = img.copy() gray = cv2.cvtColor(temp,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(gray, 130, 250, cv2.THRESH_BINARY) cv2.imshow("thres",thresh) contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt in contours: (x, y, w, h) = cv2.boundingRect(cnt) if(w > 300 and h > 300): left_most = tuple(cnt[cnt[:, :, 0].argmin()][0]) right_most = tuple(cnt[cnt[:, :, 0].argmax()][0]) top_most = tuple(cnt[cnt[:, :, 1].argmin()][0]) bottom_most = tuple(cnt[cnt[:, :, 1].argmax()][0]) cv2.drawContours(img,cnt,-1,(255,0,0),2) cv2.circle(img,left_most,5,(0,255,0),-1, cv2.LINE_AA) cv2.circle(img,right_most,5,(0,255,0),-1, cv2.LINE_AA) cv2.circle(img,top_most,5,(0,255,0),-1, cv2.LINE_AA) cv2.circle(img,bottom_most,5,(0,255,0),-1, cv2.LINE_AA) img = putText_Chinese(img, "西", left_most, (0, 255, 255), 30) img = putText_Chinese(img, "東", right_most, (0, 255, 255), 30) img = putText_Chinese(img, "北", top_most, (0, 255, 255), 30) img = putText_Chinese(img, "南", bottom_most, (0, 255, 255), 30) img = putText_Chinese(img, "中 國", (int(x + w/2),int(y +h/2)), (255, 255, 0), 70) cv2.imshow('contours', img) cv2.imwrite('result.bmp',img) cv2.waitKey(0) cv2.destroyAllWindows()
程式執行結果:
C++ OpenCV核心程式碼如下:
box[i] = minAreaRect(Mat(contours[i])); //計算每個輪廓最小外接矩形 if (box[i].size.width < 50 || box[i].size.height < 50) continue; //計算輪廓極值點 Point extLeft = *min_element(contours[i].begin(), contours[i].end(), [](const Point& lhs, const Point& rhs) { return lhs.x < rhs.x; }); Point extRight = *max_element(contours[i].begin(), contours[i].end(), [](const Point& lhs, const Point& rhs) { return lhs.x < rhs.x; }); Point extTop = *min_element(contours[i].begin(), contours[i].end(), [](const Point& lhs, const Point& rhs) { return lhs.y < rhs.y; }); Point extBot = *max_element(contours[i].begin(), contours[i].end(), [](const Point& lhs, const Point& rhs) { return lhs.y < rhs.y; });
C++ OpenCV完整原始碼將釋出在知識星球主題中,歡迎關注公眾號:OpenCV與AI深度學習。