-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 62e0a2e
Showing
23 changed files
with
1,246 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#OS junk files | ||
[Tt]humbs.db | ||
*.DS_Store | ||
|
||
#Visual Studio files | ||
*.[Oo]bj | ||
*.user | ||
*.aps | ||
*.pch | ||
*.vspscc | ||
*.vssscc | ||
*_i.c | ||
*_p.c | ||
*.ncb | ||
*.suo | ||
*.tlb | ||
*.tlh | ||
*.bak | ||
*.[Cc]ache | ||
*.ilk | ||
*.log | ||
*.lib | ||
*.sbr | ||
*.sdf | ||
*.opensdf | ||
*.unsuccessfulbuild | ||
ipch/ | ||
obj/ | ||
[Bb]in | ||
[Dd]ebug*/ | ||
[Rr]elease*/ | ||
Ankh.NoLoad | ||
|
||
#Tooling | ||
_ReSharper*/ | ||
*.resharper | ||
[Tt]est[Rr]esult* | ||
|
||
#Project files | ||
[Bb]uild/ | ||
|
||
#Subversion files | ||
.svn | ||
|
||
# Office Temp Files | ||
~$* | ||
|
||
#NuGet | ||
packages/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Drawing; | ||
using System.Drawing.Imaging; | ||
using Emgu.CV; | ||
using Emgu.CV.CvEnum; | ||
using Emgu.CV.Structure; | ||
|
||
namespace SSD2 | ||
{ | ||
static class ImagePrep | ||
{ | ||
public static Image<Bgr, Byte> ResizeImage(Image<Bgr, byte> sourceImage, int xRes, int yRes) | ||
{ | ||
return sourceImage.Resize(xRes, yRes, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC); | ||
} | ||
|
||
public static Image<Bgr, Byte> GreyscaleImage(Image<Bgr, Byte> sourceImage) | ||
{ | ||
//float[,] weights = new float[3, 3] | ||
//{ | ||
// { 0.3333f, 0.3333f, 0.3333f }, // "flat" weighting - may as well use the emgu version | ||
// { 0.3000f, 0.5900f, 0.1100f }, // standard NTSC RGB luminence weights | ||
// { 0.3086f, 0.6094f, 0.0820f } // modified weights according to http://www.graficaobscura.com/matrix/index.html | ||
//}; | ||
|
||
ColorMatrix colorMatrix = new ColorMatrix(new float[][] | ||
{ | ||
new float[] {0.3000f, 0.3000f, 0.3000f, 0, 0}, | ||
new float[] {0.5900f, 0.5900f, 0.5900f, 0, 0}, | ||
new float[] {0.1100f, 0.1100f, 0.1100f, 0, 0}, | ||
new float[] {0, 0, 0, 1, 0}, | ||
new float[] {0, 0, 0, 0, 1} | ||
}); | ||
|
||
// apply the colourmatrix to a set of image attributes | ||
ImageAttributes attributes = new ImageAttributes(); | ||
attributes.SetColorMatrix(colorMatrix); | ||
|
||
// Convert the Iimage to a bmp, | ||
Bitmap sourceBMP = sourceImage.ToBitmap(); | ||
// use it to make a blank bmp to itiate a graphics object | ||
Bitmap tempBMP = new Bitmap(sourceBMP.Width, sourceBMP.Height); | ||
Graphics graphic = Graphics.FromImage(tempBMP); | ||
// apply the source image and the color matrix (via the attributes) to the graphics obj | ||
graphic.DrawImage(sourceBMP, new Rectangle(0, 0, sourceBMP.Width, sourceBMP.Height), 0, 0, sourceBMP.Width, sourceBMP.Height, GraphicsUnit.Pixel, attributes); | ||
return new Image<Bgr, byte>(tempBMP); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.ComponentModel; | ||
using System.Data; | ||
using System.Drawing; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Windows.Forms; | ||
using System.Timers; | ||
using System.Threading; | ||
using Emgu.CV; | ||
using Emgu.CV.Structure; | ||
|
||
namespace SSD2 | ||
{ | ||
public partial class Main : Form | ||
{ | ||
|
||
// variables (replaces a settings class) | ||
double sweeptime = 1.0; | ||
double gaptime = 0.1; | ||
int xRes = 80; | ||
int yRes = 80; | ||
|
||
// Used internally | ||
private double colTicks; // Ticks per column (sweeptime/xRes) | ||
private int col = -1; // Column. From 0 to xRes. -1 is flag for "stopped" | ||
private double startTime; // Start time (in ticks) of the cycle | ||
private System.Timers.Timer timer; // Timer object | ||
private bool stopflag = false; | ||
|
||
// Image stores | ||
protected internal Image<Bgr, Byte> sourceImage; | ||
protected internal Image<Bgr, Byte> finalImage; | ||
|
||
// Classes | ||
WebCam cam; | ||
Output output; | ||
|
||
// Diagnostics | ||
int colsProcessed = 0; | ||
//public Util.RRQueue colsPerStep; | ||
//public Util.RRQueue secsPerCycle; | ||
public int cycles = 0; | ||
|
||
// Constructor | ||
public Main() | ||
{ | ||
// set up requisite classes | ||
cam = new WebCam(); | ||
cam.Init(); | ||
output = new Output(yRes); | ||
|
||
// Set up the variables | ||
colTicks = CalcColTicks(); | ||
|
||
// Set the timer to fire like crazy (1ms) | ||
timer = new System.Timers.Timer(1); | ||
timer.AutoReset = true; | ||
timer.Elapsed += new ElapsedEventHandler(nextCol); | ||
|
||
InitializeComponent(); | ||
} | ||
|
||
private int CalcColTicks() | ||
{ | ||
return (int)Math.Round(sweeptime * 10000000 / xRes); | ||
} | ||
|
||
private void nextCol(object sender, ElapsedEventArgs e) | ||
{ | ||
if (!stopflag) | ||
{ | ||
stopflag = true; | ||
int colDiff = 0; | ||
double elapsed = DateTime.Now.Ticks - startTime; | ||
int _col = (int)Math.Floor(elapsed / colTicks); | ||
if (_col >= xRes) | ||
{ | ||
newCycle(); | ||
col = 0; | ||
colDiff = _col - xRes; | ||
} | ||
else | ||
{ | ||
colDiff = _col - col; | ||
col = _col; | ||
} | ||
//statusText.Text = cycles.ToString() + ":" + col.ToString(); | ||
if (colDiff > 0) | ||
{ | ||
processCol(col); | ||
} | ||
stopflag = false; | ||
} | ||
} | ||
|
||
private void newCycle() | ||
{ | ||
if (gaptime > 0) | ||
{ | ||
timer.Enabled = false; | ||
output.Pause(); | ||
Thread.Sleep((int)(gaptime * 1000)); | ||
} | ||
double efficiency = (100 * colsProcessed / xRes); | ||
Console.WriteLine("{0} / {1} = {2}%", colsProcessed.ToString(), xRes, efficiency.ToString("0")); | ||
UpdateStatus("Running (" + efficiency.ToString() + "% efficiency)"); | ||
sourceImage = cam.grab(); | ||
Image<Bgr,Byte> lowRes = ImagePrep.ResizeImage(sourceImage, xRes, yRes); | ||
finalImage = ImagePrep.GreyscaleImage(lowRes); | ||
this.imageBox.Image = finalImage; | ||
startTime = DateTime.Now.Ticks; | ||
cycles++; | ||
colsProcessed = 0; | ||
if (gaptime > 0) | ||
{ | ||
timer.Enabled = true; | ||
} | ||
} | ||
|
||
public double cycleProgress() | ||
{ | ||
double progress; | ||
if (col == 0) progress = 0; | ||
if (col > 0) | ||
{ | ||
progress = (double)col / (double)xRes; | ||
} | ||
else progress = -1; | ||
return progress; | ||
} | ||
|
||
private void processCol(int col) | ||
{ | ||
if (finalImage != null) | ||
{ | ||
double[] colData = new double[yRes]; | ||
for (int i = 0; i < yRes; i++) | ||
{ | ||
try | ||
{ | ||
// cunning trick - because the image has been "monochromed" it doesn't matter if we choose R, G, or B | ||
colData[i] = finalImage.Data[i, col, 0]; | ||
// third index is RGB, 0 = R | ||
} | ||
catch | ||
{ | ||
return; | ||
} | ||
} | ||
output.useCol(colData, cycleProgress()); | ||
colsProcessed++; | ||
} | ||
} | ||
|
||
private void Main_Load(object sender, EventArgs e) | ||
{ | ||
timer.Enabled = true; | ||
this.newCycle(); | ||
UpdateStatus("Running"); | ||
} | ||
|
||
private void imageBox_Click(object sender, EventArgs e) | ||
{ | ||
Console.WriteLine("Image clicked"); | ||
if (timer.Enabled) | ||
{ | ||
timer.Enabled = false; | ||
output.Pause(); | ||
UpdateStatus("Paused"); | ||
} | ||
else | ||
{ | ||
timer.Enabled = true; | ||
} | ||
} | ||
|
||
delegate void UpdateStatusCallback(string text); | ||
|
||
private void UpdateStatus(string status) | ||
{ | ||
if (this.statusStrip1.InvokeRequired) | ||
{ | ||
UpdateStatusCallback d = new UpdateStatusCallback(UpdateStatus); | ||
this.Invoke(d, new object[] { status }); | ||
} | ||
else | ||
{ | ||
toolStripStatusLabel1.Text = status; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.