如何使用OpenCV检测房间边界

时间:2017-09-28 04:21:08

标签: opencv image-processing

我想清理平面图并检测墙壁。我找到了这个解决方案,但很难理解代码。 特别是这一行(如何删除房间内的文本和其他对象?)

DeleteSmallComponents[Binarize[img, {0, .2}]];

https://mathematica.stackexchange.com/questions/19546/image-processing-floor-plan-detecting-rooms-borders-area-and-room-names-t

img = Import["http://i.stack.imgur.com/qDhl7.jpg"]
nsc = DeleteSmallComponents[Binarize[img, {0, .2}]];
m = MorphologicalTransform[nsc, {"Min", "Max"}]

我如何对OpenCV做同样的事情?

1 个答案:

答案 0 :(得分:2)

在opencv中,处理图像的方法略有不同。为了做一些计算,你必须以更低级的方式思考。低级别的意思是在基本的图像处理操作中思考。

例如,您显示的行:

DeleteSmallComponents[Binarize[img, {0, .2}]];

可以通过算法在opencv中表示:

  1. 二进制图像
  2. 形态开/关或简单的膨胀/侵蚀(基于物体和背景的颜色):

    cv::threshold(img, img, 100, 255, CV_THRESH_BINARY);
    cv::dilate(img, img, cv::Mat());
    cv::dilate(img, img, cv::Mat());
    
  3. enter image description here

    此外,您可以实现自己的距离转换,或者使用例如命中注册程序(基本在opencv中实现)来检测角落:

    cv::Mat kernel = (cv::Mat_<int>(7, 7) <<
        0, 1, 0,0,0,0,0,
        -1, 1, 0,0,0,0,0,
        -1, 1, 0,0,0,0,0,
        -1,1,0,0,0,0,0,
        -1,1,0,0,0,0,0,
        -1,1,1,1,1,1,1,
        -1,-1,-1,-1,-1,-1,0);
    cv::Mat left_down,left_up,right_down,right_up;
    cv::morphologyEx(img, left_down, cv::MORPH_HITMISS, kernel);
    cv::flip(kernel, kernel, 1);
    cv::morphologyEx(img, right_down, cv::MORPH_HITMISS, kernel);
    cv::flip(kernel, kernel, 0);
    cv::morphologyEx(img, right_up, cv::MORPH_HITMISS, kernel);
    cv::flip(kernel, kernel, 1);
    cv::morphologyEx(img, left_up, cv::MORPH_HITMISS, kernel);
    

    然后你会得到这样的照片:

    left_down corners 还有一张更大点的图片(单次扩张后):

    enter image description here 最后,您可以处理找到的角落坐标以确定房间。

    编辑:用于&#34;双壁线&#34;喜欢: enter image description here

    我们必须&#34;合并&#34;首先是双壁线,所以代码将如下所示:

     cv::threshold(img, img, 220, 255, CV_THRESH_BINARY);
     cv::dilate(img, img, cv::Mat()); //small object textures
     cv::erode(img, img, cv::getStructuringElement(CV_SHAPE_RECT, cv::Size(5, 5)),cv::Point(-1,-1),2);
     cv::dilate(img, img, cv::getStructuringElement(CV_SHAPE_RECT, cv::Size(5, 5)), cv::Point(-1, -1), 3);
    

    结果图片:

    enter image description here

    可悲的是,如果图像属性发生变化,则必须稍微更改算法参数。有可能提供一般解决方案,但你必须确定大多数可能的问题变体,它会更复杂。