public FormDetectForDatabase(DetectMode mode) { this.mode = mode; InitializeComponent(); switch (mode) { case DetectMode.SNAPS: { this.Text = Program.ResourceManager.GetString("Title_DetectSnapshots"); textBox_extensions.Text = ".jpg;.png;.bmp;.gif;.jpeg;.tiff;.tif;.tga;.ico"; if (Program.Settings.Database_FoldersSnapshots == null) Program.Settings.Database_FoldersSnapshots = new System.Collections.Specialized.StringCollection(); foreach (string folder in Program.Settings.Database_FoldersSnapshots) { if (Directory.Exists(folder)) listView1.Items.Add(folder, 0); } break; } case DetectMode.COVERS: { this.Text = Program.ResourceManager.GetString("Title_DetectCovers"); textBox_extensions.Text = ".jpg;.png;.bmp;.gif;.jpeg;.tiff;.tif;.tga;.ico"; if (Program.Settings.Database_FoldersCovers == null) Program.Settings.Database_FoldersCovers = new System.Collections.Specialized.StringCollection(); foreach (string folder in Program.Settings.Database_FoldersCovers) { if (Directory.Exists(folder)) listView1.Items.Add(folder, 0); } break; } case DetectMode.INFOS: { this.Text = Program.ResourceManager.GetString("Title_DetectInfoFiles"); textBox_extensions.Text = ".txt;.doc;.rtf"; if (Program.Settings.Database_FoldersInfos == null) Program.Settings.Database_FoldersInfos = new System.Collections.Specialized.StringCollection(); foreach (string folder in Program.Settings.Database_FoldersInfos) { if (Directory.Exists(folder)) listView1.Items.Add(folder, 0); } break; } case DetectMode.MANUALS: { this.Text = Program.ResourceManager.GetString("Title_DetectManuals"); textBox_extensions.Text = ".pdf"; if (Program.Settings.Database_FoldersManuals == null) Program.Settings.Database_FoldersManuals = new System.Collections.Specialized.StringCollection(); foreach (string folder in Program.Settings.Database_FoldersManuals) { if (Directory.Exists(folder)) listView1.Items.Add(folder, 0); } break; } } }
/// <summary> /// Detect basic elements (such as circlr, line, rectangle and triangle) /// </summary> /// <param name="argPath"></param> /// <param name="argMode"></param> /// <returns></returns> public static DetectBasicEleementResult DetectBasicElement(string argPath, DetectMode argMode) { //Load the image from file and resize it for display Image <Rgb, byte> img = new Image <Rgb, byte>(argPath).Resize(400, 400, Emgu.CV.CvEnum.Inter.Linear, true); return(DetectBasicElement(img, argMode)); }
public FormDetectForDatabase(DetectMode mode) { this.mode = mode; InitializeComponent(); switch (mode) { case DetectMode.SNAPS: { this.Text = Program.ResourceManager.GetString("Title_DetectSnapshots"); textBox_extensions.Text = ".jpg;.png;.bmp;.gif;.jpeg;.tiff;.tif;.tga;.ico"; if (Program.Settings.Database_FoldersSnapshots == null) { Program.Settings.Database_FoldersSnapshots = new System.Collections.Specialized.StringCollection(); } foreach (string folder in Program.Settings.Database_FoldersSnapshots) { if (Directory.Exists(folder)) { listView1.Items.Add(folder, 0); } } break; } case DetectMode.COVERS: { this.Text = Program.ResourceManager.GetString("Title_DetectCovers"); textBox_extensions.Text = ".jpg;.png;.bmp;.gif;.jpeg;.tiff;.tif;.tga;.ico"; if (Program.Settings.Database_FoldersCovers == null) { Program.Settings.Database_FoldersCovers = new System.Collections.Specialized.StringCollection(); } foreach (string folder in Program.Settings.Database_FoldersCovers) { if (Directory.Exists(folder)) { listView1.Items.Add(folder, 0); } } break; } case DetectMode.INFOS: { this.Text = Program.ResourceManager.GetString("Title_DetectInfoFiles"); textBox_extensions.Text = ".txt;.doc;.rtf"; if (Program.Settings.Database_FoldersInfos == null) { Program.Settings.Database_FoldersInfos = new System.Collections.Specialized.StringCollection(); } foreach (string folder in Program.Settings.Database_FoldersInfos) { if (Directory.Exists(folder)) { listView1.Items.Add(folder, 0); } } break; } case DetectMode.MANUALS: { this.Text = Program.ResourceManager.GetString("Title_DetectManuals"); textBox_extensions.Text = ".pdf"; if (Program.Settings.Database_FoldersManuals == null) { Program.Settings.Database_FoldersManuals = new System.Collections.Specialized.StringCollection(); } foreach (string folder in Program.Settings.Database_FoldersManuals) { if (Directory.Exists(folder)) { listView1.Items.Add(folder, 0); } } break; } } }
static void Main(string[] args) { const int NoiseSilencerEffect = 10; ChannelType channelType = ChannelType.Null; AudioFileReader audioStream = null; long currentBaseOffset = 0; float[] buffer = null; int bufferPointer = 0; long peakCount = 0; TextWriter outRawWriter = null; string outputDirectory = null; float upperPeak, lowerPeak; Tuple <float, long> peak = new Tuple <float, long>(0, 0); long lastPeakOffset = 0; bool upper = true; Speeds speed = Speeds.s600bps; int OnePeaks; int ZeroPeaks; int ThresholdPeakCount; int TypicalOneCount; int TypicalZeroCount; int peakCount1 = 0; int peakCount0 = 0; bool?[] shiftRegister = new bool?[11]; DetectMode currentMode = DetectMode.WaitHeader; int valueCounter = 0; string currentFileName = ""; byte[] currentFileImage = new byte[32767]; int currentFileImageSize = 0; bool bitsInPeakLog = true; int tryingBits = 0; #if DEBUG var waveRecorder = new List <Tuple <float, long> >(); var peakRecorder = new List <Tuple <float, long> >(); var waveLogEnabled = false; #endif if (args.Length == 0) { Console.Error.WriteLine("Soft CMT Interface by autumn"); Console.Error.WriteLine("usage: softcmtif INPUT_FILE_NAME [--verbose] [--300|--600|--1200] [--right|--left|--average|--maximum] [--peaklog FILE_NAME] [--bitsinpeaklog] [--outraw FILE_NAME] [--outdir PATH]"); return; } bool bVerbose = false; bool peaklogWaiting = false; bool outRawWaiting = false; bool outDirWaiting = false; foreach (var item in args.Skip(1)) { if (peaklogWaiting) { peaklogWriter = File.CreateText(item); peaklogWaiting = false; } else if (outRawWaiting) { outRawWriter = File.CreateText(item); outRawWaiting = false; } else if (outDirWaiting) { outputDirectory = item; outDirWaiting = false; } else if (item == "--verbose") { bVerbose = true; } else if (item == "--right") { channelType = ChannelType.Right; } else if (item == "--left") { channelType = ChannelType.Left; } else if (item == "--average") { channelType = ChannelType.Average; } else if (item == "--maximum") { channelType = ChannelType.Maximum; } else if (item == "--bitsinpeaklog") { bitsInPeakLog = true; } else if (item == "--peaklog") { peaklogWaiting = true; } else if (item == "--outraw") { outRawWaiting = true; } else if (item == "--outdir") { outDirWaiting = true; } else if (item == "--300") { speed = Speeds.s300bps; } else if (item == "--600") { speed = Speeds.s600bps; } else if (item == "--1200") { speed = Speeds.s1200bps; } else { Console.WriteLine($"Unknwon option {item}"); return; } } if (bVerbose) { Console.WriteLine($"File Length: {new FileInfo(args[0]).Length}"); } using (audioStream = new AudioFileReader(args[0])) { audioStream.Position = 0; setSpeed(); clearShiftRegister(); if (bVerbose) { Console.WriteLine($"Audio Stream Length: {audioStream.Length}"); Console.WriteLine($"BlockAlign: {audioStream.BlockAlign}"); Console.WriteLine($"Channels: {audioStream.WaveFormat.Channels}"); Console.WriteLine($"BitsPerSample: {audioStream.WaveFormat.BitsPerSample}"); Console.WriteLine($"Encoding: {audioStream.WaveFormat.Encoding}"); Console.WriteLine($"ExtraSize: {audioStream.WaveFormat.ExtraSize}"); Console.WriteLine($"SampleRate: {audioStream.WaveFormat.SampleRate}"); } if (audioStream.WaveFormat.Channels == 1) { if (channelType != ChannelType.Null) { Console.WriteLine("Mono file not support --right|--left|--average"); return; } } else if (audioStream.WaveFormat.Channels == 2) { if (channelType == ChannelType.Null) { channelType = ChannelType.Maximum; } } else { Console.WriteLine($"Not supported channels {audioStream.WaveFormat.Channels}"); return; } if (bVerbose) { Console.WriteLine($"Channel selected: ChannelType:{channelType}"); } // detect upper peak and lower peak audioStream.Position = 0; upperAndLowerPeak(); // detect wave peaks audioStream.Position = 0; peakCount1 = 0; peakCount0 = 0; currentBaseOffset = 0; #if DEBUG waveLogEnabled = true; #endif for (; ;) { var d = readUnit(); if (d == null) { break; } //if (peaklogWriter != null) peaklogWriter.WriteLine($"[{d.Item1} {d.Item2}]"); if (upper) { if (d.Item1 > peak.Item1) { peak = d; } else if (d.Item1 < 0.0f) { setPeak(d, false); } } else { if (d.Item1 < peak.Item1) { peak = d; } else if (d.Item1 > 0.0f) { setPeak(d, true); } } } //float[] samples = new float[audioStream.Length / audioStream.BlockAlign * audioStream.WaveFormat.Channels]; //audioStream.Read(samples, 0, samples.Length); // playback //var outputDevice = new WaveOutEvent(); //outputDevice.Init(audioStream); //outputDevice.Play(); //await Task.Delay(10000); if (bVerbose) { Console.WriteLine($"Detected: {peakCount} peaks."); } } if (peaklogWriter != null) { peaklogWriter.Close(); } if (outRawWriter != null) { outRawWriter.Close(); } Console.WriteLine("Done"); #if DEBUG void waveLogSaver() { //Console.WriteLine($"waveRecorder.Count()=={waveRecorder.Count()}"); //Console.WriteLine($"waveRecorder[0].Item2=={waveRecorder[0].Item2}"); //Console.WriteLine($"waveRecorder[1].Item2=={waveRecorder[1].Item2}"); using (var w = File.CreateText("wavelog1.csv")) { //var waves = waveRecorder.TakeLast(300); var waves = waveRecorder; foreach (var item in waves) { w.WriteLine($"{item.Item2},{item.Item1}"); } } using (var w = File.CreateText("peaklog1.csv")) { foreach (var item in peakRecorder.TakeLast(100)) { w.WriteLine($"{item.Item2},{item.Item1}"); } } Console.WriteLine("Fatal Exit"); if (peaklogWriter != null) { peaklogWriter.Close(); } if (outRawWriter != null) { outRawWriter.Close(); } Environment.Exit(0); } #endif void saveFile() { if (outputDirectory == null) { Console.WriteLine("If you want to save this file, use --outdir option"); return; } var fullpath = Path.Combine(outputDirectory, DateTime.Now.ToString("yyyyMMddHHmmss") + " " + currentFileName + ".bin"); using (var stream = File.Create(fullpath)) { stream.Write(currentFileImage, 0, currentFileImageSize - 9 + 2); } Console.WriteLine($"{fullpath} saved"); } void fileDetector(int value) { if (currentMode == DetectMode.WaitHeader) { if (value == 0xd3) { valueCounter++; if (valueCounter >= 10) { valueCounter = 0; currentFileName = ""; currentMode = DetectMode.GettingFileName; } } else { valueCounter = 0; } } else if (currentMode == DetectMode.GettingFileName) { if (value != 0) { currentFileName += (char)value; } valueCounter++; if (valueCounter >= 6) { Console.WriteLine($"Found: {currentFileName} (N-BASIC Binary Image)"); valueCounter = 0; currentMode = DetectMode.GettingBody; currentFileImageSize = 0; goToCarrierDetectMode(); } } else if (currentMode == DetectMode.GettingBody) { currentFileImage[currentFileImageSize++] = (byte)value; if (value == 0) { valueCounter++; if (valueCounter == 12) { saveFile(); valueCounter = 0; currentMode = DetectMode.WaitHeader; goToCarrierDetectMode(); } } else { valueCounter = 0; } } } void notifyByte(int value) { if (peaklogWriter != null) { peaklogWriter.WriteLine($"BYTE {value:X2}"); } if (outRawWriter != null) { outRawWriter.Write((char)value); } fileDetector(value); // TBW } void clearShiftRegister() { for (int i = 0; i < shiftRegister.Length; i++) { shiftRegister[i] = true; } } void tapeReadError() { Console.WriteLine($"Tape Read Error [offset:{currentBaseOffset + bufferPointer}]"); //Environment.Exit(0); waveLogSaver(); } void notifyBit(bool?bit) { tryingBits++; if (bitsInPeakLog && peaklogWriter != null) { peaklogWriter.WriteLine($"[{bit} {peakCount0} {peakCount1}]"); } for (int i = 0; i < shiftRegister.Length - 1; i++) { shiftRegister[i] = shiftRegister[i + 1]; } shiftRegister[shiftRegister.Length - 1] = bit; // check start bit and two stop bit if (shiftRegister[0] == false && shiftRegister[9] == true && shiftRegister[10] == true) { // found frame var val = 0; for (int j = 0; j < 8; j++) { val >>= 1; if (shiftRegister[j + 1] == true) { val |= 0x80; } else if (shiftRegister[j + 1] == null) { if (carrierDetectMode == CDMode.TryingFirstByte) { carrierDetectMode = CDMode.TransferMode; return; } tapeReadError(); return; } } notifyByte(val); if (carrierDetectMode == CDMode.TryingFirstByte) { carrierDetectMode = CDMode.TransferMode; } clearShiftRegister(); } else if (tryingBits == 10) { if (carrierDetectMode == CDMode.TryingFirstByte) { carrierDetectMode = CDMode.CarrierDetecting; } } } void setPeak(Tuple <float, long> d, bool upperValue) { #if DEBUG if (waveLogEnabled) { peakRecorder.Add(d); } #endif var timeOffset = (peak.Item2 - lastPeakOffset) / audioStream.WaveFormat.Channels; notifyPeak(timeOffset); //if (peaklogWriter != null) peaklogWriter.WriteLine($"PEAK {timeOffset} {peak.Item2}"); lastPeakOffset = peak.Item2; peak = d; upper = upperValue; } void goToCarrierDetectMode() { carrierDetectMode = CDMode.CarrierDetecting; } void notifyPeak(long timeOffset) { peakCount++; //if (bVerbose && peakCount < 20) Console.Write($"{timeOffset},"); var b = timeOffset < ThresholdPeakCount; //if (peaklogWriter != null) peaklogWriter.WriteLine($"[{(b ? 1 : 0)}]"); if (carrierDetectMode == CDMode.CarrierDetecting) { if (b == false) { return; } carrierDetectMode = CDMode.CarrierDetected; return; } else if (carrierDetectMode == CDMode.CarrierDetected) { if (b == true) { return; } carrierDetectMode = CDMode.TryingFirstByte; clearShiftRegister(); tryingBits = 0; peakCount1 = 0; peakCount0 = 1; return; } if (b) { peakCount1++; } else { peakCount0++; } if (peakCount1 == OnePeaks && peakCount0 == 0) { notifyBit(true); peakCount1 = 0; peakCount0 = 0; } else if (peakCount1 == 0 && peakCount0 == ZeroPeaks) { notifyBit(false); peakCount1 = 0; peakCount0 = 0; } else if (peakCount1 + peakCount0 * 2 >= OnePeaks) { #if DEBUG if (bufferPointer + currentBaseOffset == 5380) { waveLogSaver(); } #endif notifyBit(null); peakCount1 = 0; peakCount0 = 0; if (carrierDetectMode == CDMode.TryingFirstByte) { carrierDetectMode = CDMode.CarrierDetecting; } } } float[] readBlock() { var buf = new float[256]; var bytes = audioStream.Read(buf, 0, buf.Length); if (bytes == 0) { return(null); } return(buf); } Tuple <float, long> readRawUnit() { if (buffer == null || bufferPointer >= buffer.Length) { buffer = readBlock(); if (buffer == null) { return(null); } //currentBaseOffset = audioStream.Position; currentBaseOffset += bufferPointer; bufferPointer = 0; } var v = buffer[bufferPointer]; #if NOISE_SILENCER_ENABLE // noise silencer if (v > 0 && v < upperPeak / NoiseSilencerEffect) { v = 0; //if (peaklogWriter != null) peaklogWriter.WriteLine("Detect upper cancel"); } if (v < 0 && v > lowerPeak / NoiseSilencerEffect) { v = 0; //if (peaklogWriter != null) peaklogWriter.WriteLine("Detect lower cancel"); } #endif var r = new Tuple <float, long>(v, bufferPointer + currentBaseOffset); bufferPointer++; return(r); } Tuple <float, long> readUnit() { Tuple <float, long> t = null; var l = readRawUnit(); if (l == null) { return(null); } if (audioStream.WaveFormat.Channels == 1) { t = l; } else { var r = readRawUnit(); if (r == null) { return(null); } switch (channelType) { case ChannelType.Left: t = l; break; case ChannelType.Right: t = r; break; case ChannelType.Maximum: if (r.Item1 >= 0 && l.Item1 >= 0) { t = new Tuple <float, long>(Math.Max(r.Item1, l.Item1), l.Item2); } else { t = new Tuple <float, long>(Math.Min(r.Item1, l.Item1), l.Item2); } break; default: t = new Tuple <float, long>((r.Item1 + l.Item1) / 2, l.Item2); break; } } #if DEBUG if (waveLogEnabled) { waveRecorder.Add(t); } #endif return(t); } void setSpeed() { TypicalZeroCount = (int)(1.0 / 1200 / 2 * audioStream.WaveFormat.SampleRate); TypicalOneCount = (int)(1.0 / 2400 / 2 * audioStream.WaveFormat.SampleRate); ThresholdPeakCount = (TypicalZeroCount + TypicalOneCount) / 2; if (bVerbose) { Console.WriteLine($"TypicalZeroCount:{TypicalZeroCount} TypicalOneCount:{TypicalOneCount} ThresholdPeakCount:{ThresholdPeakCount}"); } switch (speed) { case Speeds.s300bps: OnePeaks = 8 * 2; ZeroPeaks = 4 * 2; break; case Speeds.s600bps: OnePeaks = 4 * 2; ZeroPeaks = 2 * 2; break; default: OnePeaks = 2 * 2; ZeroPeaks = 1 * 2; break; } } void upperAndLowerPeak() { upperPeak = 0.0f; lowerPeak = 0.0f; for (; ;) { var pair = readUnit(); if (pair == null) { break; } if (upperPeak < pair.Item1) { upperPeak = pair.Item1; } if (lowerPeak > pair.Item1) { lowerPeak = pair.Item1; } } if (bVerbose) { Console.WriteLine($"Detect upperPeak/lowerPeak: {upperPeak}/{lowerPeak}"); } } }
/// <summary> /// Detect basic elements (such as circlr, line, rectangle and triangle) /// </summary> /// <param name="argPath"></param> /// <param name="argtMode"></param> /// <returns></returns> public static DetectBasicEleementResult DetectBasicElement(string argPath, DetectMode argtMode) { StringBuilder msgBuilder = new StringBuilder("Performance: "); //Load the image from file and resize it for display Image <Bgr, byte> img = new Image <Bgr, byte>(argPath).Resize(400, 400, Emgu.CV.CvEnum.Inter.Linear, true); //Convert the image to grayscale and filter out the noise UMat uimage = new UMat(); CvInvoke.CvtColor(img, uimage, ColorConversion.Bgr2Gray); //use image pyr to remove noise UMat pyrDown = new UMat(); CvInvoke.PyrDown(uimage, pyrDown); CvInvoke.PyrUp(pyrDown, uimage); //Image<Gray, Byte> gray = img.Convert<Gray, Byte>().PyrDown().PyrUp(); #region circle detection CircleF[] circles = null; Stopwatch watch = new Stopwatch(); double cannyThreshold = 180.0; if (argtMode == DetectMode.IncludeCircle) { watch = Stopwatch.StartNew(); double circleAccumulatorThreshold = 120; circles = CvInvoke.HoughCircles(uimage, HoughType.Gradient, 2.0, 20.0, cannyThreshold, circleAccumulatorThreshold, 5); watch.Stop(); msgBuilder.Append(String.Format("Hough circles - {0} ms; ", watch.ElapsedMilliseconds)); } #endregion #region Canny and edge detection watch.Reset(); watch.Start(); double cannyThresholdLinking = 120.0; UMat cannyEdges = new UMat(); CvInvoke.Canny(uimage, cannyEdges, cannyThreshold, cannyThresholdLinking); LineSegment2D[] lines = CvInvoke.HoughLinesP(cannyEdges, 1, //Distance resolution in pixel-related units Math.PI / 45.0, //Angle resolution measured in radians. 20, //threshold 30, //min Line width 10); //gap between lines watch.Stop(); msgBuilder.Append(String.Format("Canny & Hough lines - {0} ms; ", watch.ElapsedMilliseconds)); #endregion #region Find triangles and rectangles watch.Reset(); watch.Start(); List <Triangle2DF> triangleList = new List <Triangle2DF>(); List <RotatedRect> boxList = new List <RotatedRect>(); //a box is a rotated rectangle using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); int count = contours.Size; for (int i = 0; i < count; i++) { using (VectorOfPoint contour = contours[i]) using (VectorOfPoint approxContour = new VectorOfPoint()) { CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true); if (CvInvoke.ContourArea(approxContour, false) > 250) //only consider contours with area greater than 250 { if (approxContour.Size == 3) //The contour has 3 vertices, it is a triangle { Point[] pts = approxContour.ToArray(); triangleList.Add(new Triangle2DF(pts[0], pts[1], pts[2])); } else if (approxContour.Size == 4) //The contour has 4 vertices. { #region determine if all the angles in the contour are within [80, 100] degree bool isRectangle = true; Point[] pts = approxContour.ToArray(); LineSegment2D[] edges = PointCollection.PolyLine(pts, true); for (int j = 0; j < edges.Length; j++) { double angle = Math.Abs(edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j])); if (angle < 80 || angle > 100) { isRectangle = false; break; } } #endregion if (isRectangle) { boxList.Add(CvInvoke.MinAreaRect(approxContour)); } } } } } } watch.Stop(); msgBuilder.Append(String.Format("Triangles & Rectangles - {0} ms; ", watch.ElapsedMilliseconds)); #endregion return(new DetectBasicEleementResult(img, triangleList, boxList, circles, lines, msgBuilder.ToString())); }