zoukankan      html  css  js  c++  java
  • C#实现bitmap图像矫正

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Collections;
    using System.Diagnostics;
    using System.Drawing.Imaging;
    
     
    
    //窗体调用
    
    private Bitmap RotateImage(Bitmap bmp, double angle)
            {
                Graphics g = null;
                Bitmap tmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format32bppRgb);
                tmp.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);
                g = Graphics.FromImage(tmp);
                try
                {
                    g.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height);
                    g.RotateTransform((float)angle);
                    g.DrawImage(bmp, 0, 0);
                }
                finally
                {
                    g.Dispose();
                }
                return tmp;
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
    
               string fnIn = "f:\test\image0097_4.tif";
                string fnOut = "f:\test\output.tif";
                Bitmap bmpIn = new Bitmap(fnIn);
                gmseDeskew sk = new gmseDeskew(bmpIn);
                double skewangle = sk.GetSkewAngle();
                Bitmap bmpOut = RotateImage(bmpIn, -skewangle);
                bmpOut.Save(fnOut, ImageFormat.Tiff);//此处简单保存,可采用压缩方式保存
                       }
    
    #region 算法处理类
    
    public class gmseDeskew
        {
            public class HougLine
            {
                // Count of points in the line.
                public int Count;
                // Index in Matrix.
                public int Index;
                // The line is represented as all x,y that solve y*cos(alpha)-x*sin(alpha)=d 
                public double Alpha;
                public double d;
            }
            Bitmap cBmp;
            double cAlphaStart = -20;
            double cAlphaStep = 0.2;
            int cSteps = 40 * 5;
            double[] cSinA;
            double[] cCosA;
            double cDMin;
            double cDStep = 1;
            int cDCount;
            // Count of points that fit in a line.
            int[] cHMatrix;
            public double GetSkewAngle()
            {
                gmseDeskew.HougLine[] hl = null;
                int i = 0;
                double sum = 0;
                int count = 0;
                // Hough Transformation 
    
               Calc();
                // Top 20 of the detected lines in the image.
                hl = GetTop(20);
                // Average angle of the lines
                for (i = 0; i <= 19; i++)
                {
                    sum += hl[i].Alpha;
                    count += 1;
                }
                return sum / count;
            }
            private HougLine[] GetTop(int Count)
            {
                HougLine[] hl = null;
                int i = 0;
                int j = 0;
                HougLine tmp = null;
                int AlphaIndex = 0;
                int dIndex = 0;
                hl = new HougLine[Count + 1];
                for (i = 0; i <= Count - 1; i++)
                {
                    hl[i] = new HougLine();
                }
                for (i = 0; i <= cHMatrix.Length - 1; i++)
                {
                    if (cHMatrix[i] > hl[Count - 1].Count)
                    {
                        hl[Count - 1].Count = cHMatrix[i];
                        hl[Count - 1].Index = i;
                        j = Count - 1;
                        while (j > 0 && hl[j].Count > hl[j - 1].Count)
                        {
                            tmp = hl[j];
                            hl[j] = hl[j - 1];
                            hl[j - 1] = tmp; j -= 1;
                        }
                    }
                }
                for (i = 0; i <= Count - 1; i++)
                {
                    dIndex = hl[i].Index / cSteps;
                    AlphaIndex = hl[i].Index - dIndex * cSteps;
                    hl[i].Alpha = GetAlpha(AlphaIndex);
                    hl[i].d = dIndex + cDMin;
                }
                return hl;
            }
            public gmseDeskew(Bitmap bmp)
            {
                cBmp = bmp;
            }
            private void Calc()
            {
                int x = 0;
                int y = 0;
                int hMin = cBmp.Height / 4;
                int hMax = cBmp.Height * 3 / 4;
                Init();
                for (y = hMin; y <= hMax; y++)
                {
                    for (x = 1; x <= cBmp.Width - 2; x++)
                    {    // Only lower edges are considered.
                        if (IsBlack(x, y))
                        {
                            if (!IsBlack(x, y + 1))
                            {
                                Calc(x, y);
                            }
                        }
                    }
                }
            }
            private void Calc(int x, int y)
            {
                int alpha = 0;
                double d = 0;
                int dIndex = 0;
                int Index = 0;
                for (alpha = 0; alpha <= cSteps - 1; alpha++)
                {
                    d = y * cCosA[alpha] - x * cSinA[alpha];
                    dIndex = (int)CalcDIndex(d);
                    Index = dIndex * cSteps + alpha;
                    try
                    {
                        cHMatrix[Index] += 1;
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                    }
                }
            }
            private double CalcDIndex(double d)
            {
                return Convert.ToInt32(d - cDMin);
            }
            private bool IsBlack(int x, int y)
            {
                Color c = default(Color);
                double luminance = 0;
                c = cBmp.GetPixel(x, y);
                luminance = (c.R * 0.299) + (c.G * 0.587) + (c.B * 0.114);
                return luminance < 140;
            }
            private void Init()
            {
                int i = 0;
                double angle = 0;
                // Precalculation of sin and cos. 
                cSinA = new double[cSteps];
                cCosA = new double[cSteps];
                for (i = 0; i <= cSteps - 1; i++)
                {
                    angle = GetAlpha(i) * Math.PI / 180.0;
                    cSinA[i] = Math.Sin(angle);
                    cCosA[i] = Math.Cos(angle);
                }  // Range of d: 
                cDMin = -cBmp.Width;
                cDCount = (int)(2 * (cBmp.Width + cBmp.Height) / cDStep);
                cHMatrix = new int[cDCount * cSteps + 1];
            }
            public double GetAlpha(int Index)
            {
                return cAlphaStart + Index * cAlphaStep;
            }
        }
    
    #endregion

    具体算法为:由左边界开始扫描,从开始发现黑色素到黑色素达到平均值,在这个距离内的长度和版心的高度通过直角三角形的函数进行换算,这样就知道了倾斜的角度。

  • 相关阅读:
    森林病虫防治系统 (七)
    森林病虫防治系统 (六)
    森林病虫防治系统 (五)
    森林病虫防治系统 (四)
    森林病虫防治系统 (三)
    森林病虫防治系统 (二.2)
    森林病虫防治系统 (二.1)
    森林病虫防治系统(二)
    森林病虫防治系统 (一)
    java web 机试
  • 原文地址:https://www.cnblogs.com/longyi/p/4635014.html
Copyright © 2011-2022 走看看