title: Detect display corners with Emgu
body: <p>I want to detect a display on an image (more precisely its corners).
  I segment the image in display color and not display color:</p>
  
  <pre><code>Image&lt;Gray, byte&gt; segmentedImage = greyImage.InRange(new Gray(180), new Gray(255));
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/4mVnA.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4mVnA.jpg" alt="enter image description here"></a></p>
  
  <p>Then I use corner Harris to find the corners:</p>
  
  <pre><code>Emgu.CV.Image&lt;Emgu.CV.Structure.Gray, Byte&gt; harrisImage = new Image&lt;Emgu.CV.Structure.Gray, Byte&gt;(greyImage.Size);
  CvInvoke.CornerHarris(segmentedImage, harrisImage, 2);
  CvInvoke.Normalize(harrisImage, harrisImage, 0, 255, NormType.MinMax, DepthType.Cv32F);
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/HAMZ3.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/HAMZ3.jpg" alt="enter image description here"></a></p>
  
  <p>There are now white pixels in the corners, but I cannot access them:</p>
  
  <pre><code>for (int j = 0; j &lt; harrisImage.Rows; j++)
  {
      for (int i = 0; i &lt; harrisImage.Cols; i++)
      {
          Console.WriteLine(harrisImage[j, i].Intensity);
      }
  }
  </code></pre>
  
  <p>It writes only 0s. How can I access them? And if I can access them, how can I find the 4 corners of the screen in the harris image? Is there a function to find a perspectively transformed rectangle from points?</p>
  
  <p>EDIT:<br>
  On the OpenCV IRC they said FindContours is not that precise. And when I try to run it on the segmentedImage, I get this:
  <a href="https://i.stack.imgur.com/ydDHB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ydDHB.png" alt="enter image description here"></a>
  (ran FindContours on the segmentedImage, then ApproxPolyDP and drew the found contour on the original greyscale image)<br>
  I cannot get it to find the contours more precise...</p>
  
  <p>EDIT2:
  I cannot get this to work for me. Even with your code, I get the exact same result...
  Here is my full Emgu code:</p>
  
  <pre><code>Emgu.CV.Image&lt;Emgu.CV.Structure.Gray, Byte&gt; imageFrameGrey = new Image&lt;Emgu.CV.Structure.Gray, Byte&gt;(bitmap);
  Image&lt;Gray, byte&gt; segmentedImage = imageFrameGrey.InRange(new Gray(180), new Gray(255));
  // get rid of small objects
  int morph_size = 2;
  Mat element = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new System.Drawing.Size(2 * morph_size + 1, 2 * morph_size + 1), new System.Drawing.Point(morph_size, morph_size));
  CvInvoke.MorphologyEx(segmentedImage, segmentedImage, Emgu.CV.CvEnum.MorphOp.Open, element, new System.Drawing.Point(-1, -1), 1, Emgu.CV.CvEnum.BorderType.Default, new MCvScalar());
  
  // Find edges that form rectangles
  List&lt;RotatedRect&gt; boxList = new List&lt;RotatedRect&gt;();
  using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
  {
      CvInvoke.FindContours(segmentedImage, contours, null, Emgu.CV.CvEnum.RetrType.External, ChainApproxMethod.ChainApproxSimple);
      int count = contours.Size;
      for (int i = 0; i &lt; count; i++)
      {
          using (VectorOfPoint contour = contours[i])
          using (VectorOfPoint approxContour = new VectorOfPoint())
          {
              CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.01, true);
              if (CvInvoke.ContourArea(approxContour, false) &gt; 10000)
              {
                  if (approxContour.Size == 4)
                  {
                      bool isRectangle = true;
                      System.Drawing.Point[] pts = approxContour.ToArray();
                      LineSegment2D[] edges = Emgu.CV.PointCollection.PolyLine(pts, true);
                      for (int j = 0; j &lt; edges.Length; j++)
                      {
                          double angle = Math.Abs(edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j]));
                          if (angle &lt; 80 || angle &gt; 100)
                          {
                              isRectangle = false;
                              break;
                          }
                      }
  
                      if (isRectangle)
                      boxList.Add(CvInvoke.MinAreaRect(approxContour));
                  }
              }
          }
      }
  }
  </code></pre>