2017-02-28 99 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