title: emgucv: pan card improper skew detection in C#
body: <p>I am having three image of pan card for testing skew of image using emgucv and c#.</p>
  <p>1st image which is on top Detected 180 degree working properly.</p>
  <p>2nd image which is in middle  Detected 90 dgree should detected as 180 degree.</p>
  <p>3rd image Detected 180 degree should detected as 90 degree.</p>
  <p><a href="https://i.stack.imgur.com/ndhAd.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ndhAd.jpg" alt="Detected 180 degree working properly" /></a>
  <a href="https://i.stack.imgur.com/YaMoO.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YaMoO.jpg" alt="Detected 90 should detected as 180" /></a></p>
  <p><a href="https://i.stack.imgur.com/GkWFv.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GkWFv.jpg" alt="Detected 180 should detected as 90" /></a></p>
  <p>One observation I am having that i wanted to share here is when i crop unwanted part of image from up and down side of pan card using paint brush, it gives me expected result using below mention code.</p>
  <p>Now i wanted to understand how i can remove the unwanted part using programming.
  I have played with contour and roi but I am not able to figure out how to fit the same. I am not able to understand whether emgucv itself selects contour or I have to do something.</p>
  <p>Please suggest any suitable code example.</p>
  <p>Please check code below for angle detection and please help me. Thanks in advance.</p>
  <pre><code>imgInput = new Image&lt;Bgr, byte&gt;(impath);
            Image&lt;Gray, Byte&gt; img2 = imgInput.Convert&lt;Gray, Byte&gt;();
            Bitmap imgs;
            Image&lt;Gray, byte&gt; imgout = imgInput.Convert&lt;Gray, byte&gt;().Not().ThresholdBinary(new Gray(50), new Gray(125));
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            Emgu.CV.Mat hier = new Emgu.CV.Mat();
            var blurredImage = imgInput.SmoothGaussian(5, 5, 0 , 0);
            CvInvoke.AdaptiveThreshold(imgout, imgout, 255, Emgu.CV.CvEnum.AdaptiveThresholdType.GaussianC, Emgu.CV.CvEnum.ThresholdType.Binary, 5, 45);
  
            CvInvoke.FindContours(imgout, contours, hier, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
            if (contours.Size &gt;= 1)
            {
                for (int i = 0; i &lt;= contours.Size; i++)
                {
  
                    Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);
                    RotatedRect box = CvInvoke.MinAreaRect(contours[i]);
                    PointF[] Vertices = box.GetVertices();
                    PointF point = box.Center;
                    PointF edge1 = new PointF(Vertices[1].X - Vertices[0].X, Vertices[1].Y - Vertices[0].Y);
                    PointF edge2 = new PointF(Vertices[2].X - Vertices[1].X, Vertices[2].Y - Vertices[1].Y);
                    double r = edge1.X + edge1.Y;
                    double edge1Magnitude = Math.Sqrt(Math.Pow(edge1.X, 2) + Math.Pow(edge1.Y, 2));
                    double edge2Magnitude = Math.Sqrt(Math.Pow(edge2.X, 2) + Math.Pow(edge2.Y, 2));
                    PointF primaryEdge = edge1Magnitude &gt; edge2Magnitude ? edge1 : edge2;
                    double primaryMagnitude = edge1Magnitude &gt; edge2Magnitude ? edge1Magnitude : edge2Magnitude;
                    PointF reference = new PointF(1, 0);
                    double refMagnitude = 1;
                    double thetaRads = Math.Acos(((primaryEdge.X * reference.X) + (primaryEdge.Y * reference.Y)) / (primaryMagnitude * refMagnitude));
                    double thetaDeg = thetaRads * 180 / Math.PI;
                    imgInput = imgInput.Rotate(thetaDeg, new Bgr());
                    imgout = imgout.Rotate(box.Angle, new Gray());
                    Bitmap bmp = imgout.Bitmap;
                    break;
                }
  
            }
  </code></pre>