public static Bitmap RotateBicubic(Bitmap bmp, int degree) { // create filter - rotate for 30 degrees keeping original image size RotateBicubic filter = new RotateBicubic(degree, true); // apply the filter Bitmap newImage = filter.Apply(bmp); return bmp; }
public static Bitmap Find(Blob blob, BlobCounter blobCounter, FoundColorSpaces colorSpaces) { List<IntPoint> blobPoints = new List<IntPoint>(); List<IntPoint> leftPoints, rightPoints; blobCounter.GetBlobsLeftAndRightEdges(blob, out leftPoints, out rightPoints); Bitmap bmp = new Bitmap(blob.Rectangle.Width, blob.Rectangle.Height, PixelFormat.Format24bppRgb); for (int c = 0; c < leftPoints.Count; c++) { IntPoint startLeft = leftPoints[c]; IntPoint endRight = rightPoints[c]; for (int x = startLeft.X; x <= endRight.X; x++) { blobPoints.Add(new IntPoint(x - blob.Rectangle.Left, startLeft.Y - blob.Rectangle.Top)); bmp.SetPixel(x - blob.Rectangle.Left, startLeft.Y - blob.Rectangle.Top, colorSpaces.OriginalColorSpace.GetPixel(x, startLeft.Y)); } } double[,] aData = new double[blobPoints.Count, 2]; double[,] eData = new double[blobPoints.Count, 2]; double[] bData = new double[blobPoints.Count]; double centroidX = 0; double centroidY = 0; double total = 0; for (int c = 0; c < blobPoints.Count; c++) { centroidX += blobPoints[c].X; centroidY += blobPoints[c].Y; total++; } centroidX /= total; centroidY /= total; for (int c = 0; c < blobPoints.Count; c++) { eData[c, 0] = blobPoints[c].X - centroidX; eData[c, 1] = blobPoints[c].Y - centroidY; aData[c, 0] = 1; aData[c, 1] = blobPoints[c].X; bData[c] = blobPoints[c].Y; } DenseMatrix E = DenseMatrix.OfArray(eData); DenseMatrix Eprime = (DenseMatrix)E.TransposeThisAndMultiply(E); DenseEvd eigen = new DenseEvd(Eprime); Vector<Complex> eigenValues = eigen.EigenValues(); int maxIndex = 0; double max = 0.0; for (int c = 0; c < eigenValues.Count; c++) { double eigenvalue = eigenValues[c].Real; if (eigenvalue > max) { max = eigenvalue; maxIndex = c; } } Matrix<double> eigenVectors = eigen.EigenVectors(); Vector<double> maxEigenVector = eigenVectors.Column(maxIndex); Matrix<double> xHat = DenseMatrix.OfColumns(2, 1, new List<Vector<double>>(new Vector<double>[] { maxEigenVector })); double radians = System.Math.Asin(xHat[0, 0]); double degrees = radians * (180 / System.Math.PI); // Why doesn't this work? //DenseMatrix A = DenseMatrix.OfArray(aData); //DenseVector b = new DenseVector(bData); //Matrix<double> xHat = (A.TransposeThisAndMultiply(A).Inverse() * A.Transpose() * b).ToColumnMatrix(); RotateBicubic rotate = new RotateBicubic(-degrees); bmp = rotate.Apply(bmp); return bmp; }
/// <summary> /// Rotate an image using trial and error until a best angle is found (measured by a vertical histogram). /// </summary> /// <param name="drawHistogramBarsBecauseTheyreCool"> /// Saying TRUE here makes the image unusable, but you can save the image to a file and it looks cool with all the pretty histogram lines on it... /// </param> public void ResizeRotateCut(bool drawHistogramBarsBecauseTheyreCool) { try { Bitmap copy = new Bitmap(Image.Width, Image.Height, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(copy); g.DrawImage(Image, 0, 0, Image.Width, Image.Height); Bitmap rot; int best = copy.Height; double ang = 0.0; copy = copy.CropResize(); for (double d = -45.0; d <= 45.0; d += 5.0) { RotateBicubic r = new RotateBicubic(d); r.FillColor = Color.White; r.KeepSize = false; rot = r.Apply(copy); int hist = GetHistogram(rot, 7); if (hist < best) { best = hist; ang = d; } //Pen p1 = new Pen(new SolidBrush(Color.FromArgb(128, Color.Red))); //Pen p2 = new Pen(new SolidBrush(Color.FromArgb(128, Color.LimeGreen))); //Bitmap rot2 = new Bitmap(600, 600); //using (Graphics g2 = Graphics.FromImage(rot2)) //{ // g2.Clear(Color.White); // g2.DrawImage(rot, rot2.Width / 2 - rot.Width / 2, rot2.Height - rot.Height); // for (int x = 0; x < rot2.Width; x++) // { // int count = 0; // for (int y = 0; y < rot2.Height; y++) // { // if (rot2.GetPixel(x, y).Subtract(Color.White) > 10) // { // count++; // } // } // if (count > rot2.Height / 15) // { // double percent = (double)count / rot2.Height; // g2.DrawLine(p1, x, (int)((rot2.Height - 1) * (1.0 - percent)), x, rot2.Height - 1); // } // else // { // g2.DrawLine(p2, x, 0, x, rot2.Height - 1); // } // } // g2.DrawString(ang.ToString("0.00") + " degrees", new Font("Tahoma", 8.25f), Brushes.Black, new PointF(1.0f, 1.0f)); //} //rot2.Save("zhist " + (90 - (45 + d)).ToString("00") + ".png"); GlobalMessage.SendMessage(rot); } RotateBicubic r2 = new RotateBicubic(ang); r2.FillColor = Color.White; r2.KeepSize = false; rot = r2.Apply(copy); GetHistogram(rot, 7); rot = rot.CropResize(); if (drawHistogramBarsBecauseTheyreCool) { Pen p1 = new Pen(new SolidBrush(Color.FromArgb(128, Color.Red))); Pen p2 = new Pen(new SolidBrush(Color.FromArgb(128, Color.LimeGreen))); using (Graphics g2 = Graphics.FromImage(rot)) { for (int x = 0; x < rot.Width; x++) { int count = 0; for (int y = 0; y < rot.Height; y++) { if (rot.GetPixel(x, y).Subtract(Color.White) > 10) { count++; } } if (count > rot.Height / 15) { double percent = (double)count / rot.Height; g2.DrawLine(p1, x, (int)((rot.Height - 1) * (1.0 - percent)), x, rot.Height - 1); } else { g2.DrawLine(p2, x, 0, x, rot.Height - 1); } } g2.DrawString(ang.ToString("0.00") + " degrees", new Font("Tahoma", 8.25f), Brushes.Black, new PointF(1.0f, 1.0f)); } } Image = rot; GlobalMessage.SendMessage(Image); } catch (Exception ex) { throw new ImageProcessingException("Error rotating an image to find the best vertical histogram.", ex); } }
public static Bitmap rotate(this Bitmap bitmap, int degrees) { AForge.Imaging.Filters.RotateBicubic filter = new AForge.Imaging.Filters.RotateBicubic(degrees); return(filter.Apply(AForge.Imaging.Image.Clone(bitmap, PixelFormat.Format24bppRgb))); }
private static UnmanagedImage RotateImage(KindleProfile profile, UnmanagedImage image) { if (image.Width > image.Height) { UnmanagedImage output; RotateBicubic filter = new RotateBicubic(90); output = filter.Apply(image); return output; } return image; }