2017-02-28 37 views
0

我想实现类似这样使用OpenCV的获得来自OpenCV的距离奇怪的结果变换

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

不过,我遇到了一些墙壁的东西(可能是由于我自己的无知与OpenCV的工作) 。

当我尝试对图像执行距离转换时,我没有得到预期的结果。

这是我与

enter image description here

该工作的原始图像的图像做一些清理与OpenCV中后,我得到

enter image description here

这是wierdness后,我得到试图在上面的图像上运行距离转换。我的理解是,这应该看起来更像一个模糊的热图。如果我按照opencv的例子通过了这一点,并尝试运行一个阈值来找到距离峰值,我只会得到一个黑色的图像。 enter image description here

这是代码迄今为止,我已经拼凑起来使用一些不同的OpenCV的例子

cv::Mat outerBox = cv::Mat(matImage.size(), CV_8UC1); 
cv::Mat kernel = (cv::Mat_<uchar>(3,3) << 0,1,0,1,1,1,0,1,0); 

for(int x = 0; x < 3; x++) { 
    cv::GaussianBlur(matImage, matImage, cv::Size(11,11), 0); 
    cv::adaptiveThreshold(matImage, outerBox, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 5, 2); 
    cv::bitwise_not(outerBox, outerBox); 

    cv::dilate(outerBox, outerBox, kernel); 
    cv::dilate(outerBox, outerBox, kernel); 

    removeBlobs(outerBox, 1); 

    erode(outerBox, outerBox, kernel); 
} 

cv::Mat dist; 
cv::bitwise_not(outerBox, outerBox); 
distanceTransform(outerBox, dist, cv::DIST_L2, 5); 
// Normalize the distance image for range = {0.0, 1.0} 
// so we can visualize and threshold it 
normalize(dist, dist, 0, 1., cv::NORM_MINMAX); 


    //using a threshold at this point like the opencv example shows to find peaks just returns a black image right now 
//threshold(dist, dist, .4, 1., CV_THRESH_BINARY); 
//cv::Mat kernel1 = cv::Mat::ones(3, 3, CV_8UC1); 
//dilate(dist, dist, kernel1); 


self.mainImage.image = [UIImage fromCVMat:outerBox]; 

void removeBlobs(cv::Mat &outerBox, int iterations) { 
int count=0; 
int max=-1; 

cv::Point maxPt; 

for(int iteration = 0; iteration < iterations; iteration++) { 

    for(int y=0;y<outerBox.size().height;y++) 
    { 
     uchar *row = outerBox.ptr(y); 
     for(int x=0;x<outerBox.size().width;x++) 
     { 
      if(row[x]>=128) 
      { 

       int area = floodFill(outerBox, cv::Point(x,y), CV_RGB(0,0,64)); 

       if(area>max) 
       { 
        maxPt = cv::Point(x,y); 
        max = area; 
       } 
      } 
     } 

    } 

    floodFill(outerBox, maxPt, CV_RGB(255,255,255)); 
    for(int y=0;y<outerBox.size().height;y++) 
    { 
     uchar *row = outerBox.ptr(y); 
     for(int x=0;x<outerBox.size().width;x++) 
     { 
      if(row[x]==64 && x!=maxPt.x && y!=maxPt.y) 
      { 
       int area = floodFill(outerBox, cv::Point(x,y), CV_RGB(0,0,0)); 
      } 
     } 
    } 
} 
} 

我一直在敲打我这头几个小时,我完全陷进泥上,所以任何帮助将不胜感激。这有点超出我的深度,我觉得我可能只是在没有意识到的情况下在某个地方犯了一些基本的错误。

编辑: 使用相同的代码上面运行的OpenCV的Mac(不是的iOS)我得到预期的结果 enter image description here

这似乎表明,这个问题是和Mat - > UIImage的弥合OpenCV的建议使用。我将推动使用Mac库来测试我的代码,但它确实很好,能够从UIImage桥接中获得一致的结果。

+ (UIImage*)fromCVMat:(const cv::Mat&)cvMat 
{ 
    // (1) Construct the correct color space 
    CGColorSpaceRef colorSpace; 
    if (cvMat.channels() == 1) { 
     colorSpace = CGColorSpaceCreateDeviceGray(); 
    } else { 
     colorSpace = CGColorSpaceCreateDeviceRGB(); 
    } 

    // (2) Create image data reference 
    CFDataRef data = CFDataCreate(kCFAllocatorDefault, cvMat.data, (cvMat.elemSize() * cvMat.total())); 

    // (3) Create CGImage from cv::Mat container 
    CGDataProviderRef provider = CGDataProviderCreateWithCFData(data); 
    CGImageRef imageRef = CGImageCreate(cvMat.cols, 
             cvMat.rows, 
             8, 
             8 * cvMat.elemSize(), 
             cvMat.step[0], 
             colorSpace, 
             kCGImageAlphaNone | kCGBitmapByteOrderDefault, 
             provider, 
             NULL, 
             false, 
             kCGRenderingIntentDefault); 

    // (4) Create UIImage from CGImage 
    UIImage * finalImage = [UIImage imageWithCGImage:imageRef]; 

    // (5) Release the references 
    CGImageRelease(imageRef); 
    CGDataProviderRelease(provider); 
    CFRelease(data); 
    CGColorSpaceRelease(colorSpace); 

    // (6) Return the UIImage instance 
    return finalImage; 
} 
+0

你有没有试图改变的背景为黑色而不是白色的清理平面图,做距离变换过吗? –

+0

您的问题的图像已经消失。 – m3h0w

+0

@ m3h0w似乎imgur有容量问题。图像也为我而来。 – bojangles

回答

1

我计算出使用python在OpenCV的距离变换,我能取得这样的:

enter image description here

你说:“我什么也没得到,但黑色的图像”。嗯,我最初面临的同样的问题,直到我转换的图像通过键入intnp.uint8(dist_transform)

我做了一些额外的以及(你可能/可能不会需要它)。为了在一定程度上分割房间,我对距离变换后的图像执行了阈值。我得到这个结果:

enter image description here

+1

感谢您的输入! 我激活了openCV的mac版本并将我的代码复制过来,当用imshow显示图像时,我得到了非常相似的结果。然而,我仍然在iOS版本上看到了使用OpenCV提供的在Mat和UIImage之间提供的桥接生成的UIImage。好消息是,这意味着我的代码可能一直在工作,坏消息是我可能需要使用Mac版本的库进行测试,这很令人沮丧。 – bojangles