opencv获取图片像素坐标_利用OpenCV从图片中提取矩形并标注坐标(室内平面地图)(一)
?某城市會(huì)展中心室內(nèi)地圖
背景
一名室內(nèi)設(shè)計(jì)師的日常工作從設(shè)計(jì)一張會(huì)展地圖開始。常常有這樣的場(chǎng)景:劃分除規(guī)范的展位后,進(jìn)入銷售階段,頻繁的需要修改這張地圖,如展示拆分、合并、換位置、標(biāo)記已交易。
問題
從上圖中標(biāo)記色塊的是有效展位,經(jīng)過設(shè)計(jì)師設(shè)計(jì)確定了坐標(biāo)、尺寸、編號(hào)(不重要)。需要解決的是從圖片中提取出色塊的精確位置和尺寸,然后通過html5展示到頁面上;后續(xù)修改操作(合并、拆分等)完全通過頁面在完成。
提取矩形頂點(diǎn)坐標(biāo)
矩形的檢測(cè)主要是提取邊緣,圖中色塊部分明顯有別于周圍顏色(指灰度),我們可以將圖片灰度,將展位部分與過道部分明顯的分別開,對(duì)后續(xù)做邊緣計(jì)算就非常有幫助。
檢測(cè)矩形并提取坐標(biāo)需要對(duì)圖像進(jìn)行預(yù)處理、邊緣檢測(cè)、提取輪廓、檢測(cè)凸包(或者最小矩形)、頂點(diǎn)獲取。
圖片預(yù)處理
由于圖片的特性,只要做轉(zhuǎn)灰度、中值濾波
img = cv2.imread(url)# 灰度圖,濾波gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)gray = cv2.medianBlur(gray, 15)處理后的圖片如下
處理后的圖片
邊緣檢測(cè)
# 邊緣CANNY_THRESH_1 = 90CANNY_THRESH_2 = 120edges = cv2.Canny(gray, CANNY_THRESH_1, CANNY_THRESH_2)edges = cv2.dilate(edges, None, iterations=3)edges = cv2.erode(edges, None, iterations=1)邊緣特征比較明顯,不同的圖片系數(shù)差別不大。當(dāng)前系數(shù)效果可以使用。更細(xì)的參數(shù)沒有調(diào)整。
另外做了一些放大和腐蝕,把不需要的一些小的文字區(qū)域過濾掉了。方便過濾不需要的輪廓。
提取輪廓
# 查找輪廓contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 顯示所有輪廓mask = np.zeros(img.shape)for c in contours: # 過濾小面積 if (cv2.contourArea(c) < scale ** 2): continue cv2.drawContours(mask, [c], 0, (0, 0, 255))cv2.imshow('contours', mask)關(guān)于函數(shù)findContours介紹可以參考:https://www.cnblogs.com/yiyi20120822/p/11506970.html
提取到的輪廓
提取到的輪廓基本完整,屬于規(guī)則的圓角矩形。上圖因?yàn)閺棿颁秩締栴}顯示不全,其實(shí)紅色的框是一個(gè)非常漂亮地閉合矩形。
這里更具不同參數(shù)可提取不同的輪廓,這里我只去了最外層。另外我需要的是規(guī)則矩形,因此不需要額外的尋找凸包-提取頂點(diǎn)。用一個(gè)比較單間的最小包圍矩形就能得到想要的結(jié)果。
提取矩形獲取頂點(diǎn)
rect = cv2.minAreaRect(cnt)box = cv2.boxPoints(rect)box = np.int0(box)# 打印box的結(jié)果,每一組四個(gè)point順時(shí)針顯示# 第一個(gè)矩形[[5350 4899] [5350 4784] [5791 4784] [5791 4899]]# 第二個(gè)矩形[[4804 4900] [4804 4785] [5247 4785] [5247 4900]]# ……結(jié)束
截止到這里,已經(jīng)得到了需要的基礎(chǔ)數(shù)據(jù)信息。根據(jù)坐標(biāo)信息即可把展位還原到頁面上。
完整代碼附上
#!/usr/bin/python3# coding:utf-8# description: 標(biāo)記地圖的色塊位置# user: arik# @time: 2020/1/3 10:45import cv2import numpy as npimport log### url: 圖片地址# scale: 圖片比例,例如 3m=100px,3m是圖片的基本單元尺寸# #def get_rectangle(url, scale=100): img = cv2.imread(url) # 灰度圖,濾波 gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) gray = cv2.medianBlur(gray, 15) # cv2.imshow('line', gray) # 邊緣 CANNY_THRESH_1 = 90 CANNY_THRESH_2 = 120 edges = cv2.Canny(gray, CANNY_THRESH_1, CANNY_THRESH_2) edges = cv2.dilate(edges, None, iterations=3) edges = cv2.erode(edges, None, iterations=1) # 查找輪廓 contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) json_res = [] # mask = np.zeros(img.shape) for c in contours: # 過濾小面積 if (cv2.contourArea(c) < scale ** 2): continue rect = cv2.minAreaRect(c) box = cv2.boxPoints(rect) box = np.int0(box) # cv2.drawContours(mask, [c], 0, (0, 0, 255)) box = key_point_2_array(box) json_res.append(box) # 輸出到文件 log.json_log(json_res) # 顯示圖片 # cv2.imshow('line', mask)### point轉(zhuǎn)數(shù)組# #def key_point_2_array(box): res = [] for p in box: res.append([p[0], p[1]]) return resif __name__ == "__main__": get_rectangle('images/origin/map1.jpg', 100) # cv2.waitKey(0) # cv2.destroyAllWindows()下一篇文章補(bǔ)充頁面還原問題。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的opencv获取图片像素坐标_利用OpenCV从图片中提取矩形并标注坐标(室内平面地图)(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基金是直接卖出好还是转换好?基金转换你操
- 下一篇: 没有不良信用为什么信用卡会被降额