title: Technique to introduce normalisation/consistency to std dev comparison?
body: <p>I am implementing a very simple segmentation algorithm for single channel images. The algorithm works like so:</p>
  
  <p>For a single channel image:  </p>
  
  <ol>
  <li>Calculate the standard deviation, ie, measure how much the luminosity varies across the image.  </li>
  <li><p>If the stddev > 15 (aka threshold):  </p>
  
  <ul>
  <li>Divide the image into 4 cells/images  </li>
  <li>For each cell:  
  
  <ul>
  <li>Repeat step 1 and step 2 (go recursive)   </li>
  </ul></li>
  </ul>
  
  <p>Else:  </p>
  
  <ul>
  <li>Draw a rectangle on the source image to signify a segment lies in these bounds. </li>
  </ul></li>
  </ol>
  
  <p>My problem occurs because my threshold is constant and when I go recursive <code>15</code> is not longer a good signifier of whether that image is homogeneous or not. <strong>How can I introduce consistency/normalisation to my homogeneity check?</strong></p>
  
  <p>Should I resize each image to the same size (100x100)? Should my threshold be formula? Say <code>15 / img.rows * img.cols</code> or <code>15 / MAX_HISTOGRAM_PEAK</code>?</p>
  
  <p><strong>Edit</strong> Code:</p>
  
  <pre><code>void split_mat(const Mat&amp; src, Mat&amp; split1, Mat&amp; split2, Mat&amp; split3, Mat&amp; split4) {
  
      split1 = Mat(src, Rect(Point(0, 0), Point(src.cols / 2, src.rows / 2)));
      split1 = Mat(src, Rect(Point(src.cols/2, 0), Point(src.cols, src.rows / 2)));
      split3 = Mat(src, Rect(Point(0, src.rows/2), Point(src.cols / 2, src.rows)));
      split4 = Mat(src, Rect(Point(src.cols/2, src.rows/2), Point(src.cols, src.rows)));
  }
  
  void segment_by_homogeny(const Mat&amp; src, double threshold) {
  
      Scalar mean, stddev;
      meanStdDev(src, mean, stddev);
  
      double dev = stddev[0]; // / (src.rows * src.cols) * 100.0;
  
      if (dev &gt;= threshold) {
          Mat s1, s2, s3, s4;
          split_mat(src, s1, s2, s3, s4);
  
          // Go recursive and segment each sub-segment where necessary
          segment_by_homogeny(s1, threshold);
          segment_by_homogeny(s2, threshold);
          segment_by_homogeny(s3, threshold);
          segment_by_homogeny(s4, threshold);
      }
      else {
          // Store 'segment' in global vector 'images' 
          // and write std dev on it
          char d[255];
          sprintf_s(d, "Std Dev: %f", stddev[0]);
          putText(src, d, cvPoint(30, 60),
              FONT_HERSHEY_COMPLEX_SMALL, 0.7, cvScalar(200, 200, 250), 1, CV_AA);
          images.push_back(src);
      }
  }
  
  
  // current usage for the example image results in inifinite recursion. 
  // The green and red segment never has a std dev &lt; 25
  segment_by_homogeny(img, 25); 
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/Nhzf9.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Nhzf9.png" alt="enter image description here"></a></p>
  
  <p>I am expecting my algorithm to produce the following 5 segments:</p>
  
  <p><a href="https://i.stack.imgur.com/Q3TWA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Q3TWA.png" alt="enter image description here"></a></p>