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, , , bmp.Width, bmp.Height);
g.RotateTransform((float)angle);
g.DrawImage(bmp, , );
}
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 = -;
double cAlphaStep = 0.2;
int cSteps = * ;
double[] cSinA;
double[] cCosA;
double cDMin;
double cDStep = ;
int cDCount;
// Count of points that fit in a line.
int[] cHMatrix;
public double GetSkewAngle()
{
gmseDeskew.HougLine[] hl = null;
int i = ;
double sum = ;
int count = ;
// Hough Transformation Calc();
// Top 20 of the detected lines in the image.
hl = GetTop();
// Average angle of the lines
for (i = ; i <= ; i++)
{
sum += hl[i].Alpha;
count += ;
}
return sum / count;
}
private HougLine[] GetTop(int Count)
{
HougLine[] hl = null;
int i = ;
int j = ;
HougLine tmp = null;
int AlphaIndex = ;
int dIndex = ;
hl = new HougLine[Count + ];
for (i = ; i <= Count - ; i++)
{
hl[i] = new HougLine();
}
for (i = ; i <= cHMatrix.Length - ; i++)
{
if (cHMatrix[i] > hl[Count - ].Count)
{
hl[Count - ].Count = cHMatrix[i];
hl[Count - ].Index = i;
j = Count - ;
while (j > && hl[j].Count > hl[j - ].Count)
{
tmp = hl[j];
hl[j] = hl[j - ];
hl[j - ] = tmp; j -= ;
}
}
}
for (i = ; i <= Count - ; 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 = ;
int y = ;
int hMin = cBmp.Height / ;
int hMax = cBmp.Height * / ;
Init();
for (y = hMin; y <= hMax; y++)
{
for (x = ; x <= cBmp.Width - ; x++)
{ // Only lower edges are considered.
if (IsBlack(x, y))
{
if (!IsBlack(x, y + ))
{
Calc(x, y);
}
}
}
}
}
private void Calc(int x, int y)
{
int alpha = ;
double d = ;
int dIndex = ;
int Index = ;
for (alpha = ; alpha <= cSteps - ; alpha++)
{
d = y * cCosA[alpha] - x * cSinA[alpha];
dIndex = (int)CalcDIndex(d);
Index = dIndex * cSteps + alpha;
try
{
cHMatrix[Index] += ;
}
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 = ;
c = cBmp.GetPixel(x, y);
luminance = (c.R * 0.299) + (c.G * 0.587) + (c.B * 0.114);
return luminance < ;
}
private void Init()
{
int i = ;
double angle = ;
// Precalculation of sin and cos.
cSinA = new double[cSteps];
cCosA = new double[cSteps];
for (i = ; i <= cSteps - ; 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)( * (cBmp.Width + cBmp.Height) / cDStep);
cHMatrix = new int[cDCount * cSteps + ];
}
public double GetAlpha(int Index)
{
return cAlphaStart + Index * cAlphaStep;
}
} #endregion
具体算法为:由左边界开始扫描,从开始发现黑色素到黑色素达到平均值,在这个距离内的长度和版心的高度通过直角三角形的函数进行换算,这样就知道了倾斜的角度。
C#实现bitmap图像矫正的更多相关文章
- [翻译]开发文档:android Bitmap的高效使用
内容概述 本文内容来自开发文档"Traning > Displaying Bitmaps Efficiently",包括大尺寸Bitmap的高效加载,图片的异步加载和数据缓存 ...
- 【开源毕设】一款精美的家校互动APP分享——爱吖校推 [你关注的,我们才推](持续开源更新3)附高效动态压缩Bitmap
一.写在前面 爱吖校推如同它的名字一样,是一款校园类信息推送交流平台,这么多的家校互动类软件,你选择了我,这是我的幸运.从第一次在博客园上写博客到现在,我一次一次地提高博文的质量和代码的可读性,都是为 ...
- Android Bitmap 和 ByteArray的互相转换
Android Bitmap 和 ByteArray的互相转换 移动平台图像处理,需要将图像传给native处理,如何传递?将bitmap转换成一个 byte[] 方便传递也方便cpp代码直接处理图像 ...
- Android-Drawable、Bitmap、byte[]、资源文件相互转换
我们在Android的开发中,经常可以遇到图片的处理,当中,有很多是 Bitmap.Drawable.byte[]和资源文件它们直接相互转换. 今天就此总结一下: 1.资源文件转为Drawable 2 ...
- bitmap对海量无重复的整数排序--转
原文地址:http://blog.csdn.net/u013074465/article/details/46956295 现在有n个无重复的正整数(n 小于10的7次方),如果内存限制在1.5M以内 ...
- 基于位图(Bitmap、BitmapData)的图片处理方法(C#)
目前操作位图的主流方法有三种: 1.基于Bitmap像素的处理方法,以GetPixel()和SetPixel()方法为主.方法调用简单,但是效率偏低. 2.基于内存的像素操作方法,以System.Ru ...
- android:布局、绘制、内存泄露、响应速度、listview和bitmap、线程优化以及一些优化的建议!
1.布局优化 首先删除布局中无用的控件和层级,其次有选择地使用性能较低的viewgroup,比如布局中既可以使用RelativeLayout和LinearLayout,那我们就采用LinearLayo ...
- 获取View的截图-将View转换为Bitmap对象
开发中,有时候需要获取View的截图来做动画来达到动画流程的目的 原理:将View的内容画到一个Bitmap画布上,然后取出 下面封装了一个从View生成Bitmap的工具类 /** * 将View转 ...
- bitmap解码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BYTE unsigned c ...
随机推荐
- 小强的HTML5移动开发之路(29)—— JavaScript回顾4
一.变量的作用域 javascript脚本的执行过程分为两个阶段: 第一阶段,js引擎()先扫描整个javascript代码.当碰到<script>时,会先创建一个全局的活动对象,将< ...
- 利用spingmvc及servlet实现对url的地址去除后缀,更改后缀为html
效果图 1.在web.xml中加上如下配置.其实就是利用servlet的目录过滤,这样所有带有news的地址都会被拦截 <!-- restfull风格约定,去除前台超链接访问的后缀 --> ...
- 使用lapack图书馆逆矩阵
阿土,直接在代码: #include <string> #include "lapacke.h" #include "lapack_aux.h" i ...
- C#7模范和实践
C# 7 中的模范和实践 原文地址:https://www.infoq.com/articles/Patterns-Practices-CSharp-7 关键点 遵循 .NET Framework ...
- Numpy Usage Introduction
Reference : http://my.oschina.net/u/175377/blog/74406 试验性的Numpy教程 原文来自Tentative NumPy Tutorial 目录 先决 ...
- 解决:insert Vodafone sim card,open the mms read report,when receive the read report,cann't download..
insert Vodafone sim card,open the mms read report,when receive the read report,cann't download the m ...
- eclipes中配置javadoc文档
- [实时更新]jquery完整版下载
jquery-2.1.0 注!不再支持IE 6/7/8 直接引用地址: 开发版地址1: <script src="http://code.jquery.com/jquery-2. ...
- 5亿英镑!Imagination同意出售给私募机构Canyon Bridge
集微网最新消息,据外媒 FT 报道,Imagination Technologies Group Plc(以下简称“Imagination”)同意由中国背景的私募基金Canyon Bridge Cap ...
- 带农历日历的DatePicker控件!Xamarin控件开发小记
原文:带农历日历的DatePicker控件!Xamarin控件开发小记 闲来无事开发了个日期选择控件,感兴趣的同学前往: https://github.com/MatoApps/Mato.DatePi ...