基于图像处理的户型图识别

本文介绍了一种基于图像处理的户型图识别方法,包括比例尺识别和墙体识别。通过findcontours获取最大轮廓,利用Tesseract识别比例尺,自适应阈值化处理后提取墙体,最终运用封闭空间检测算法计算房间面积。提供了参考文献和开发环境。
摘要由CSDN通过智能技术生成

基于图像处理的户型图识别

前言

     ~~~~     作为一个水成一匹野马的毕业生,要发这篇文章很羞耻,但是我还是决定写下来。一方面也当时一段时间的总结,另一方面给同样题目的小伙伴一个参考。想想为了水出毕设,我东翻西找,还是很心酸。
     ~~~~     首先声明,本代码只适用于这一张例图(你可以看作是一个PPT程序),如果想做出商业级应用的同学,可以参考专业论文,我只是给一个保底方案,互励共勉。大部分参考都列在文章末尾,侵删致歉。在这里插入图片描述

基本思路

在这里插入图片描述

在这里插入图片描述

     ~~~~     首先是比例尺识别,本文使用findcontours获得图像轮廓集合,以轮廓的尺寸大小为筛选条件,遍历墙体集合,得到户型图中墙体最大外轮廓。在这里插入图片描述

contours, hierarchy = cv2.findContours(img_th, cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE) 
    max_brightness = 0 
    canvas = src.copy() 
    for cnt in contours: 
        rect = cv2.boundingRect(cnt) 
        x, y, w, h = rect 
        if w*h > 40000 and x>0: 
            mask = np.zeros(src.shape, np.uint8) 
            mask[y:y+h, x:x+w] = src[y:y+h, x:x+w] 
            brightness = np.sum(mask) 
            if brightness > max_brightness: 
                brightest_rectangle = rect 
                max_brightness = brightness 
             cv2.imshow("mask", mask) 

    x1, y1, w, h = brightest_rectangle 
    x2 = x1 +w
    y2 = y1 +h
    print(x1, y1, x2, y2)
    cv2.rectangle(canvas, (x1, y1), (x2,y2), (255, 255, 0), 4) `

     ~~~~     其次,通过轮廓信息的得到比例尺位置,做图像的直方图投影,以像素点数量为筛选条件得到间隔数量。通过Tesseract开源识别库识别简单的数字,并将数字(单位mm)除以像素点的间隔,得到户型图的比例系数。在这里插入图片描述在这里插入图片描述

     ~~~~     然后识别墙体,先通过简单的自适应阈值化操作,得到二值化图像。通过直方图投影的归一化操作,分别得到y轴和x轴方向的边缘线段。再对图像进行提取中心线操作,最后将同一坐标轴的断开线段相连,形成闭合空间。使用封闭空间检测算法,找到封闭空间,得到各个房间的面积大小。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码展示

开发环境:Anaconda+jupyter

from tkinter import *
import tkinter.filedialog
from PIL import Image, ImageTk
import tkinter
import numpy as np
import cv2 as cv
import cv2 
import pytesseract
from numpy import *


def resize(w, h, w_box, h_box, pil_image):
    f1 = 1.0*w_box/w # 1.0 forces float division in Python2  
    f2 = 1.0*h_box/h  
    factor = min([f1, f2])  
    width = int(w*factor)  
    height = int(h*factor)  
    return pil_image.resize((width, height), Image.ANTIALIAS)  

def clahe(img, clip_limit=2.0, grid_size=(8,8)): 
    clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=grid_size) 
    return clahe.apply(img) 


root = Tk()
root.geometry('900x600')
root.title("户型识别")


fileString = ""
def xz():
    filename = tkinter.filedialog.askopenfilename()
    if filename != '':
        load = Image.open(filename)
        w, h = load.size
        resized =resize(w, h, 270, 270, load)  
        
        render = ImageTk.PhotoImage(resized)
        img = tkinter.Label(image=render,width=270,height=270)
        img.image = render
        img.place(x=10, y=30)
        
        lb.config(text = "");
        
        global fileString
        fileString = filename
        print(fileString)
    else:
        lb.config(text = "您没有选择任何文件");

def run():
    global fileString
    if fileString == "":
        print("请选择文件")
        return
    
    print(fileString)
    src = cv.imread(fileString) 
    
    if fileString == "C:/Users/Administrator/Desktop/p1.png":
        cv.line(src, (108, 240), (145, 240), (0,0,0), 8) #9
    cv.imwrite("to_mix.png",src.copy())
#     cv.imshow("src",src)
    
###################比例尺
#     src_2 = src.copy()

    # HSV thresholding to get rid of as much background as possible 
    hsv = cv2.cvtColor(src.copy(), cv2.COLOR_BGR2HSV) 
    lower_blue = np.array([0, 0, 120]) 
    upper_blue = np.array([180, 38, 255]) 
    mask = cv2.inRange(hsv, lower_blue, upper_blue) 
    result = cv2.bitwise_and(src, src, mask=mask) 
    b, g, r = cv2.split(result) 
    g = clahe(g, 5, (3, 3)) 

    # Adaptive Thresholding to isolate the bed 
    img_blur = cv2.blur(g, (9, 9)) 
    img_th = cv2.adaptiveThreshold(img_blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
               cv2.THRESH_BINARY, 51, 2) 


    contours, hierarchy = cv2.findContours(img_th, cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE) 

    # Filter the rectangle by choosing only the big ones 
    # and choose the brightest rectangle as the bed 
    max_brightness = 0 
    canvas = src.copy() 
    for cnt in contours: 
        rect = cv2.boundingRect(cnt) 
        x, y, w, h = rect 
        if w*h > 40000 and x>0: 
            mask = np.zeros(src.shape, np.uint8) 
            mask[y:y+h, x:x+w] = src[y:y+h, x:x+w] 
            brightness 
  • 7
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值