-2

I have these two images, image 1 is a binary of image 2.

I would like to segment out the object from image 2 in the shape of image 1.

           image 1                            image 2

enter image description here enter image description here

I have looked into several samples but none of them is helpful. Thought of overlaying image 2 onto image 1's white area, using copyTo function with the conditions, but I'm sure there's a better way. Would really appreciate if someone can tell me the method or C++ snippet code to solve this!

TylerH
  • 20,799
  • 66
  • 75
  • 101
Samuel
  • 51
  • 8

2 Answers2

3

Yes, you are right.

As stated you can perform image masking instead of using copying in C++:

cv::bitwise_and(image1, image2, output);

where image1 is the mask and image2 is the original image.

Another method that works for me is this:

image2.copyTo(image1, image1);

where image1 is the mask and image2 is the original image. The result is shown below:

enter image description here

Samuel
  • 51
  • 8
Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • 1
    `setTo` with a mask is much clearer. in my opinion. – Miki Mar 14 '17 at 20:10
  • 1
    @Miki Cool. Are there any performance issues among the two? Or do both the functions take same computation time? – Jeru Luke Mar 14 '17 at 20:11
  • 2
    Probably the same.... I think that "I'm setting to this value according to this mask" is less confusing than "I'm and-ing this two images" – Miki Mar 14 '17 at 20:13
  • @JeruLuke. Thanks, It has an error "Sizes of input arguments do not match (The operation is neither 'array op array')". But I'm sure I can solve it with your method. Could you tell me the reason I get the down votes (beginner here)? I have did the research on the image segmentation for almost a day.. – Samuel Mar 14 '17 at 20:18
  • Misinterpretation of your question led to the downvotes I guess. Image **segmentation** and image **masking** are separate operations altogether. You should mentioned (or searched) for image masking. – Jeru Luke Mar 14 '17 at 20:22
  • @Samuel because 1) this question is asked every other day, 2) there's no evidence you actually tried something. You can show the code you tried in the question. – Miki Mar 14 '17 at 20:23
  • Trivial mistakes happen with beginners, I was once in your stage too :D – Jeru Luke Mar 14 '17 at 20:23
  • 1
    @Miki I actually tried the same method and faced the same error (until now). The error couldn't be solved with changing the masking channel. Was thinking I was off course, that's why I asked for method. But thanks to your explanation, I shall show some evidence next time I ask questions! :) – Samuel Mar 14 '17 at 20:30
  • @JeruLuke Thanks a lot! :D – Samuel Mar 14 '17 at 20:31
  • 1
    @Samuel I see you have worked out your problem. Great job. keep learning!!! – Jeru Luke Mar 15 '17 at 10:31
-2

You need to Otsu threshold to separate the foreground from the background

/**@file
  Get the Otusu threshold for image segmentation.
  @param[in] gray - the grayscale image
  @param width - image width
  @param height - image height
  @returns Threshold at which to split pixels into foreground and
           background.
  @image html maggie.jpg  Margaret Thatcher (1925-2013) greyscale photograph
  @image html maggieotsu.gif Mrs Thatcher Otsu thresholded
 */
int getOtsuthreshold(unsigned char *grey, int width, int height)
{
  int hist[256] = {0};
  int wB = 0;
  int wF;
  float mB, mF;
  float sum = 0;
  float sumB = 0;
  float varBetween;
  float varMax = 0.0f;
  int answer = 0;
  int i;
  int k;

  for(i=0;i<width*height;i++)
    hist[grey[i]]++;

  /* sum of all (for means) */
  for (k=0 ; k<256 ; k++) 
       sum += k * hist[k];

  for(k=0;k<256;k++)
  {
     wB += hist[k];               
     if (wB == 0) 
         continue;

     wF = width*height - wB;            
     if (wF == 0) 
       break;

     sumB += (float) (k * hist[k]);

     mB = sumB / wB;            /* Mean Background */
     mF = (sum - sumB) / wF;    /* Mean Foreground */

     /* Calculate Between Class Variance */
     varBetween = (float)wB * (float)wF * (mB - mF) * (mB - mF);

     /* Check if new maximum found */
     if (varBetween > varMax) 
     {
       varMax = varBetween;
       answer = k;
     }

  }
  return answer;
}

https://github.com/MalcolmMcLean/binaryimagelibrary

Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18
  • 1
    Are you sure you're trying to answer **this** question? Even so, you can use `cv::threshold(..., THRESH_OTSU)`... no need for an external library – Miki Mar 14 '17 at 20:06