博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#实现bitmap图像矫正
阅读量:5276 次
发布时间:2019-06-14

本文共 6206 字,大约阅读时间需要 20 分钟。

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

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

转载于:https://www.cnblogs.com/longyi/p/4635014.html

你可能感兴趣的文章
CentOS 6.4 配置LAMP 环境 与安装 phpmyadmin
查看>>
【代码笔记】iOS-在导航栏中显示等待对话框
查看>>
代码动态创建checkbox
查看>>
Linux centos ansible
查看>>
rank() over,dense_rank(),row_number() 的区别
查看>>
java transient 和Volatile关键字
查看>>
testing
查看>>
使用API动态添加删除菜单项
查看>>
spark源码编译记录
查看>>
luogu3233 世界树 (虚树)
查看>>
机器学习基础6--集群模型和算法
查看>>
Redis和Memcached整体
查看>>
git 远程仓库
查看>>
hdu3785
查看>>
解决编译apache出现的问题:configure: error: APR not found . Please read the documentation
查看>>
7kyu Exes and Ohs
查看>>
“已删除的应用” 流量高
查看>>
Java中 Iterable 和 Iterator 的区别
查看>>
hdu_2063,二分图最大匹配的学习
查看>>
layui富文本编译器添加图片
查看>>