title: Getting odd results from OpenCV distance transform
body: <p>I am trying to implement something similar to this using openCV</p>
  
  <p><a href="https://mathematica.stackexchange.com/questions/19546/image-processing-floor-plan-detecting-rooms-borders-area-and-room-names-t">https://mathematica.stackexchange.com/questions/19546/image-processing-floor-plan-detecting-rooms-borders-area-and-room-names-t</a></p>
  
  <p>However, I am running into some walls (probably due to my own ignorance in working with OpenCV).</p>
  
  <p>When I try to perform a distance transform on my image, I am not getting the expected result at all.</p>
  
  <p>This is the original image I am working with</p>
  
  <p><a href="https://i.stack.imgur.com/9RTEM.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9RTEM.png" alt="enter image description here"></a></p>
  
  <p>This is the image I get after doing some cleanup with opencv</p>
  
  <p><a href="https://i.stack.imgur.com/qvTxb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/qvTxb.png" alt="enter image description here"></a></p>
  
  <p>This is the wierdness I get after trying to run a distance transform on the above image. My understanding is that this should look more like a blurry heatmap. If I follow the opencv example passed this point and try to run a threshold to find the distance peaks, I get nothing but a black image.
  <a href="https://i.stack.imgur.com/9yD8A.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9yD8A.png" alt="enter image description here"></a></p>
  
  <p>This is the code thus far that I have cobbled together using a few different opencv examples</p>
  
  <pre><code>    cv::Mat outerBox = cv::Mat(matImage.size(), CV_8UC1);
  cv::Mat kernel = (cv::Mat_&lt;uchar&gt;(3,3) &lt;&lt; 0,1,0,1,1,1,0,1,0);
  
  for(int x = 0; x &lt; 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 &amp;outerBox, int iterations) {
  int count=0;
  int max=-1;
  
  cv::Point maxPt;
  
  for(int iteration = 0; iteration &lt; iterations; iteration++) {
  
      for(int y=0;y&lt;outerBox.size().height;y++)
      {
          uchar *row = outerBox.ptr(y);
          for(int x=0;x&lt;outerBox.size().width;x++)
          {
              if(row[x]&gt;=128)
              {
  
                  int area = floodFill(outerBox, cv::Point(x,y), CV_RGB(0,0,64));
  
                  if(area&gt;max)
                  {
                      maxPt = cv::Point(x,y);
                      max = area;
                  }
              }
          }
  
      }
  
      floodFill(outerBox, maxPt, CV_RGB(255,255,255));
      for(int y=0;y&lt;outerBox.size().height;y++)
      {
          uchar *row = outerBox.ptr(y);
          for(int x=0;x&lt;outerBox.size().width;x++)
          {
              if(row[x]==64 &amp;&amp; x!=maxPt.x &amp;&amp; y!=maxPt.y)
              {
                  int area = floodFill(outerBox, cv::Point(x,y), CV_RGB(0,0,0));
              }
          }
      }
  }
  }
  </code></pre>
  
  <p>I've been banging my head on this for a few hours and I am totally stuck in the mud on it, so any help would be greatly appreciated. This is a little bit out of my depth, and I feel like I am probably just making some basic mistake somewhere without realizing it.</p>
  
  <p>EDIT:
  Using the same code as above running OpenCV for Mac (not iOS) I get the expected results
  <a href="https://i.stack.imgur.com/cCrA3.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/cCrA3.png" alt="enter image description here"></a></p>
  
  <p>This seems to indicate that the issue is with the Mat -> UIImage bridging that OpenCV suggests using. I am going to push forward using the Mac library to test my code, but it would sure be nice to be able to get consistent results from the UIImage bridging as well.</p>
  
  <pre><code>    + (UIImage*)fromCVMat:(const cv::Mat&amp;)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;
  }
  </code></pre>