// 例子中是识别一个日期类型的字符串
using System;
using System.IO;
using System.Drawing;
using System.Threading;
using AForge;
using AForge.Video;
using AForge.Video.DirectShow;
class Program{
private FilterInfoCollection videoDevices;
private VideoCaptureDevice videoSource;
public int selectedDeviceIndex = 0;
bool bStop=false, bPause=false;
private static bool isRedirect=false;
int idx=0;
public static void Main(string[] args){
DisableConsoleLineInputMode();
if(!(null==args || args.Length<1)){
isRedirect="NOTEPAD+".Equals(args[0]);
}
Console.Title="Camera OCR Beta - q to quit";
new Program().test();
}
public void test(){
if(Environment.UserInteractive){
new Thread(ThreadKeyDetect).Start();
}
GetDevices();
VideoConnect();
GrabBitmap();
while(!bStop){
Thread.Sleep(1);
}
Disconnect();
if(!isRedirect){
Console.Write("Press any key to continue . . . ");
AnyKey_wait();
}
}
public FilterInfoCollection GetDevices() {
try{
//枚举所有视频输入设备
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
if (videoDevices.Count != 0){
Console.WriteLine("Camera list:");
foreach(FilterInfo fi in videoDevices){
Console.WriteLine(" " + fi.Name+" " + fi.MonikerString);
}
return videoDevices;
}else{
Console.WriteLine("No Camera find.");
return null;
}
}catch (Exception ex){
Console.WriteLine("error on get video device:" + ex.Message);
return null;
}
}
/// <summary>
/// 连接视频摄像头
/// </summary>
/// <param name="deviceIndex"></param>
/// <param name="resolutionIndex"></param>
/// <returns></returns>
public VideoCaptureDevice VideoConnect(){
return VideoConnect(0,0);
}
public VideoCaptureDevice VideoConnect(int deviceIndex, int resolutionIndex){
if (videoDevices.Count <= 0){
bStop=true;
return null;
}
selectedDeviceIndex = deviceIndex;
videoSource = new VideoCaptureDevice(videoDevices[deviceIndex].MonikerString);
Console.WriteLine("Connect to:"+videoDevices[deviceIndex].Name);
EnumeratedSupportedFrameSizes(videoSource);
videoSource.VideoResolution = videoCapabilities[0];
// videoDevice.ProvideSnapshots = true;
// videoDevice.SnapshotResolution = snapshotCapabilities[0];
// videoDevice.SnapshotFrame += new NewFrameEventHandler( videoDevice_SnapshotFrame );
videoSource.Start();
return videoSource;
}
//抓图,拍照,单帧
public void GrabBitmap(){
if (videoSource == null){
bStop=true;
return;
}
Console.WriteLine("Start to capture...");
videoSource.NewFrame += new NewFrameEventHandler(videoSource_NewFrame);
}
void videoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs){
if(bPause){
return;
}
Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
doOcr(bmp);
// // string fullPath = g_Path ;
// // if (!Directory.Exists(fullPath)){
// // Directory.CreateDirectory(fullPath);
// // }
// // string img = DateTime.Now.ToString("yyyyMMdd hhmmss") + ".bmp";
// // bmp.Save(img);
if(idx==50000 || bStop){
bStop=true;
//如果这里不写这个,一会儿会不停的拍照,
videoSource.NewFrame -= new NewFrameEventHandler(videoSource_NewFrame);
Console.WriteLine("Caputre done.");
return;
}
idx++;
}
private VideoCapabilities[] videoCapabilities;
// private VideoCapabilities[] snapshotCapabilities;
// Collect supported video and snapshot sizes
private void EnumeratedSupportedFrameSizes( VideoCaptureDevice videoDevice ){
// this.Cursor = Cursors.WaitCursor;
try{
videoCapabilities = videoDevice.VideoCapabilities;
// snapshotCapabilities = videoDevice.SnapshotCapabilities;
Console.WriteLine("VideoCapabilities:");
foreach ( VideoCapabilities capabilty in videoCapabilities ){
Console.WriteLine( string.Format( " {0} x {1}", capabilty.FrameSize.Width, capabilty.FrameSize.Height ) );
}
// Console.WriteLine("snapshotCapabilities:");
// foreach ( VideoCapabilities capabilty in snapshotCapabilities ){
// Console.WriteLine( string.Format( " {0} x {1}", capabilty.FrameSize.Width, capabilty.FrameSize.Height ) );
// }
}finally{
// this.Cursor = Cursors.Default;
}
}
private void Disconnect(){
if (videoSource != null ){
videoSource.SignalToStop( );// stop video device
videoSource.WaitForStop( );
videoSource= null;
//if ( videoSource.ProvideSnapshots ){
// videoSource.SnapshotFrame -= new NewFrameEventHandler( videoDevice_SnapshotFrame );
//}
}
}
public void doOcr(Bitmap bmp){
byte[]data=Bitmap2TiffBytes(bmp);
try{
using (Tesseract.TesseractEngine engine = new Tesseract.TesseractEngine(@".\tessdata", "eng", Tesseract.EngineMode.Default)){
// using (Pix img = Pix.LoadFromFile(testImagePath)){
using (Tesseract.Pix img = Tesseract.Pix.LoadTiffFromMemory(data)){
using (Tesseract.Page page = engine.Process(img, Tesseract.PageSegMode.Auto)){
string text = page.GetText();
Console.Clear();
// Console.WriteLine("Mean confidence: {0}", page.GetMeanConfidence());
// Console.WriteLine("Text:{0}", text);
isDate(text);
}
}
}
}catch (Exception ex){
Console.WriteLine("Unexpected Error: " + ex.Message);
Console.WriteLine("Details: ");
Console.WriteLine(ex.StackTrace.ToString());
}
}
private string[]rxDt=new string[]{"\\d{4}-\\d{2}-\\d{2}", "\\d{2}/\\d{2}/\\d{4}"};
private string rxTm="\\d{2}:\\d{2}:\\d{2}";
private void isDate(string text){
bool b=false;
foreach(string sd in rxDt){
// string rtext="Hypertech";
string rtext=sd+" "+rxTm;
// System.Text.RegularExpressions.Regex regex=new System.Text.RegularExpressions.Regex(rtext, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex=new System.Text.RegularExpressions.Regex(rtext);
foreach (System.Text.RegularExpressions.Match match in regex.Matches(text)){
b=true;
Console.WriteLine(match.Value);
}
}
if(b){
bPause=true;
Console.Write("Press any key to continue");
}else{
Console.Write(text);
}
}
public static byte[] Bitmap2TiffBytes(Bitmap bitmap){
using (MemoryStream stream = new MemoryStream()){
// bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff);
byte[] data = new byte[stream.Length];
stream.Seek(0, SeekOrigin.Begin);
stream.Read(data, 0, Convert.ToInt32(stream.Length));
return data;
}
}
private void AnyKey_wait(){
int c;
while(true){
c = Console.In.Read();
if(c!=-1){
break;
}
Thread.Sleep(2);
}
}
private void ThreadKeyDetect(){
// ConsoleKey c = ConsoleKey.Escape;
int Q=(byte)'Q', q=(byte)'q', esc=27;
// Console.Out.WriteLine(" Q="+Q+", q="+q);
int c;
while(true){
if( (c = Console.In.Read())!=-1 ){
// if( (c = Console.In.Peek())!=-1 ){
// while(Console.KeyAvailable){
// c=Console.ReadKey(true).Key; if(ConsoleKey.Q.CompareTo(c)==0){
if(Q==c || q==c || esc==c){
Console.Out.WriteLine("\r\nBye-bye!");
bStop=true;
break;
}else{
bPause=false;
}
}
Thread.Sleep(50);
}
}
[System.Runtime.InteropServices.DllImport("kernel32", SetLastError=true)]
private static extern IntPtr GetStdHandle(IntPtr whichHandle);
[System.Runtime.InteropServices.DllImport("kernel32", SetLastError=true)]
private static extern bool GetConsoleMode(IntPtr handle, out uint mode);
[System.Runtime.InteropServices.DllImport("kernel32", SetLastError=true)]
private static extern bool SetConsoleMode(IntPtr handle, uint mode);
private static readonly IntPtr STD_INPUT_HANDLE = new IntPtr(-10);
private const uint ENABLE_LINE_INPUT = 2;
private const uint ENABLE_ECHO_INPUT = 4;
// http://ewbi.blogs.com/develops/2005/11/net_console_pre.html
private static void DisableConsoleLineInputMode() {
IntPtr console = GetStdHandle(STD_INPUT_HANDLE);
uint oldMode;
if (GetConsoleMode(console, out oldMode)) {
uint newMode = oldMode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
if (SetConsoleMode(console, newMode)) {
return;
}
}
Console.WriteLine("Failed to get/set console input mode: " + System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString());
}
}