public static ScanAndGrade findBubbles(Bitmap input, ExamSpecifics APBiologyExam) { Bitmap stretched = new Bitmap(input, (int)(input.Width), (int)(input.Height)); Image <Gray, Byte> grayImage = new Image <Bgr, byte>(stretched).Convert <Gray, Byte>(); CvInvoke.Threshold(grayImage, grayImage, 120, 1000, Emgu.CV.CvEnum.ThresholdType.BinaryInv); Gray cannyThreshold = new Gray(1); Gray circleAccumulatorThreshold = new Gray(30); CircleF[] circles = grayImage.HoughCircles( cannyThreshold, circleAccumulatorThreshold, 1, //Resolution of the accumulator used to detect centers of the circles 1, //min distance 15, //min radius 60 //max radius )[0]; //Get the circles from the first channel Graphics f = Graphics.FromImage(input); Graphics g = Graphics.FromImage(stretched); List <Point> circleCenter = new List <Point>(); double avRadius = 0; foreach (CircleF c1 in circles) { avRadius = avRadius + c1.Radius; circleCenter.Add(new Point((int)c1.Center.X, (int)c1.Center.Y)); } avRadius = avRadius / circles.Count(); input.Save("presorted.png"); Sectionizer testSections = new Sectionizer(circleCenter, avRadius); ScanAndGrade scantron = new ScanAndGrade(stretched, testSections, APBiologyExam, avRadius); Debug.WriteLine("AP Biology Exam Score: " + scantron.FinalUnweightedScore); return(scantron); }
public BubbleSheet(string seatID, string socialID, ExamSpecifics exam, double score, bool didCheat, bool wasAbsent, List <String> multipleChoiceAnswers, List <String> pairingAnswers, List <String> trueFalseAnswers, List <String> completionAnswers, List <String> subjectiveAnswers, Bitmap correctAnswerOverylay, Bitmap incorrectAnswerOverlay, Bitmap baseSheet, Bitmap unansweredAnswerOverlay) { this.seatID = seatID; this.socialID = socialID; this.exam = exam; this.score = score; this.didCheat = didCheat; this.wasAbsent = wasAbsent; this.multipleChoiceAnswers = multipleChoiceAnswers; this.pairingAnswers = pairingAnswers; this.trueFalseAnswers = trueFalseAnswers; this.completionAnswers = completionAnswers; this.subjectiveAnswers = subjectiveAnswers; this.correctAnswerOverylay = correctAnswerOverylay; this.incorrectAnswerOverlay = incorrectAnswerOverlay; this.baseSheet = baseSheet; this.unansweredAnswerOverlay = unansweredAnswerOverlay; }
private void button1_Click(object sender, EventArgs e) { if (this.openFileDialog1.ShowDialog() == DialogResult.OK) { this.button1.Enabled = false; this.textBox1.Text = this.openFileDialog1.FileName; ExamSpecifics APBiologyExam = new ExamSpecifics(true, "AP Biology Exam", 0, "AAAAAAAAAAAAAAAAAAAA", 1, "AAAAAAAAAA", 1, "TTTTTTTTTT", 1, "1111111111", 1, 1); Bitmap input = new Bitmap(Image.FromFile(this.openFileDialog1.FileName)); BubbleSheet scanned = FullScan.scanSheet(input, APBiologyExam); this.label1.Text = "Total Score: " + scanned.score; Bitmap overimage = new Bitmap(scanned.correctAnswerOverylay.Width, scanned.correctAnswerOverylay.Height); Graphics g = Graphics.FromImage(overimage); g.DrawImage(scanned.baseSheet, new Point(0, 0)); g.DrawImage(scanned.correctAnswerOverylay, new Point(0, 0)); this.pictureBox1.Image = overimage; this.button1.Enabled = true; } }
static void Main() { /** * List<Student> roster = new List<Student>(); * roster.Add(new Student("1262050", "Zachery Utt")); * Exam quickExam = new Exam("AP Biology", 0,null,"","",30,10,10,10,5,4,10,7,1.0,1.0,1.0,1.0,1.0); **/ ExamSpecifics APBiologyExam = new ExamSpecifics(true, "AP Biology Exam", 0, "AAAAAAAAAAAAA", 1, "AAAAAAA", 1, "TTTT", 1, "111", 1, 1); // Stopwatch quicktime = new Stopwatch(); // quicktime.Start(); // Bitmap input = new Bitmap(Image.FromFile(@"C:\Users\Uttza\Desktop\toAnalyze.png")); // BubbleSheet scanned = FullScan.scanSheet(input, APBiologyExam); // scanned.save(); // Debug.WriteLine(quicktime.ElapsedMilliseconds); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Graded()); }
public static BubbleSheet scanSheet(Bitmap input, ExamSpecifics test) { RotatedRect[] barcodes = BarScan.detectBarcodes(input); Bitmap toScan = new Bitmap(input.Width, input.Height, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(toScan); g.DrawImage(input, new Point(0, 0)); g.Dispose(); toScan.SetPixel((int)barcodes[0].GetVertices()[1].X, (int)barcodes[0].GetVertices()[1].Y, Color.FromArgb(150, 0, 50)); toScan.SetPixel((int)barcodes[0].GetVertices()[3].X, (int)barcodes[0].GetVertices()[3].Y, Color.FromArgb(150, 0, 100)); toScan.SetPixel((int)barcodes[1].GetVertices()[1].X, (int)barcodes[1].GetVertices()[1].Y, Color.FromArgb(150, 50, 50)); toScan.SetPixel((int)barcodes[1].GetVertices()[3].X, (int)barcodes[1].GetVertices()[3].Y, Color.FromArgb(150, 50, 100)); Bitmap toCompartmentalize = new Bitmap(toScan.Width, toScan.Height); int minY = 0; bool found1 = false; bool isDone = false; Point p1 = new Point(); Point p2 = new Point(); Point p3 = new Point(); Point p4 = new Point(); for (int y = 0; y < toScan.Height; y++) { if (isDone) { break; } for (int x = 0; x < toScan.Width; x++) { Color c = toScan.GetPixel(x, y); if (c.R == 150) { if (c.B == 50 && c.G == 0) { p1 = new Point(x, y); } else if (c.B == 100 && c.G == 0) { p2 = new Point(x, y); } else if (c.B == 50 && c.G == 50) { p3 = new Point(x, y); } else if (c.B == 100 && c.G == 50) { p4 = new Point(x, y); } if (c.B == 100) { if (found1) { if (y > minY) { minY = y; } isDone = true; break; } else { minY = y; found1 = true; } } } } } Graphics p = Graphics.FromImage(toCompartmentalize); p.DrawImage(toScan, new Point(0, 0)); p.Dispose(); Rectangle r1 = new Rectangle(p1.X - 50, p1.Y - 50, (p2.X - p1.X) + 100, (p2.Y - p1.Y) + 100); Rectangle r2 = new Rectangle(p3.X - 50, p3.Y - 50, (p4.X - p3.X) + 100, (p4.Y - p3.Y) + 100); Barcodes quickCodes = new Barcodes(BarScan.cropImage(toCompartmentalize, r1), BarScan.cropImage(toCompartmentalize, r2)); toCompartmentalize = BarScan.cropImage(toCompartmentalize, new Rectangle(0, minY, toCompartmentalize.Width, toCompartmentalize.Height - minY)); ScanAndGrade scantron = Compartmentalize.findBubbles(toCompartmentalize, test); //CALCULATE SCORE double score = 0; score = score + (scantron.scannedScores[1].score * test.multipleChoiceWeight); score = score + (scantron.scannedScores[2].score * test.pairingWeight); score = score + (scantron.scannedScores[3].score * test.trueWeight); score = score + (scantron.scannedScores[4].score * test.compWeight); score = score + (scantron.scannedScores[5].score * test.subjectWeight); Bitmap correctAnswerOverlay = new Bitmap(toCompartmentalize.Width, toCompartmentalize.Height); Bitmap inCorrectAnswerOverlay = new Bitmap(toCompartmentalize.Width, toCompartmentalize.Height); Bitmap blankAnswerOverlay = new Bitmap(toCompartmentalize.Width, toCompartmentalize.Height); Graphics correctAnswerOverlayGraphics = Graphics.FromImage(correctAnswerOverlay); scantron.scannedScores[0].drawCorrectAnswer(correctAnswerOverlayGraphics); scantron.scannedScores[1].drawCorrectAnswer(correctAnswerOverlayGraphics); scantron.scannedScores[2].drawCorrectAnswer(correctAnswerOverlayGraphics); scantron.scannedScores[3].drawCorrectAnswer(correctAnswerOverlayGraphics); scantron.scannedScores[4].drawCorrectAnswer(correctAnswerOverlayGraphics); scantron.scannedScores[5].drawCorrectAnswer(correctAnswerOverlayGraphics); correctAnswerOverlayGraphics.Dispose(); Graphics inCorrectAnswerOverlayGraphics = Graphics.FromImage(inCorrectAnswerOverlay); scantron.scannedScores[0].drawCorrectAnswer(inCorrectAnswerOverlayGraphics); scantron.scannedScores[1].drawCorrectAnswer(inCorrectAnswerOverlayGraphics); scantron.scannedScores[2].drawCorrectAnswer(inCorrectAnswerOverlayGraphics); scantron.scannedScores[3].drawCorrectAnswer(inCorrectAnswerOverlayGraphics); scantron.scannedScores[4].drawCorrectAnswer(inCorrectAnswerOverlayGraphics); scantron.scannedScores[5].drawCorrectAnswer(inCorrectAnswerOverlayGraphics); inCorrectAnswerOverlayGraphics.Dispose(); Graphics blankAnswerOverlayGraphics = Graphics.FromImage(blankAnswerOverlay); scantron.scannedScores[0].drawCorrectAnswer(blankAnswerOverlayGraphics); scantron.scannedScores[1].drawCorrectAnswer(blankAnswerOverlayGraphics); scantron.scannedScores[2].drawCorrectAnswer(blankAnswerOverlayGraphics); scantron.scannedScores[3].drawCorrectAnswer(blankAnswerOverlayGraphics); scantron.scannedScores[4].drawCorrectAnswer(blankAnswerOverlayGraphics); scantron.scannedScores[5].drawCorrectAnswer(blankAnswerOverlayGraphics); blankAnswerOverlayGraphics.Dispose(); BubbleSheet toReturn = new BubbleSheet(quickCodes.seatID, quickCodes.socialID, test, score, (scantron.scannedScores[0] as StudentCondition).didCheat, (scantron.scannedScores[0] as StudentCondition).wasAbsent, scantron.scannedScores[1].getResponses(), scantron.scannedScores[2].getResponses(), scantron.scannedScores[3].getResponses(), scantron.scannedScores[4].getResponses(), scantron.scannedScores[5].getResponses(), correctAnswerOverlay, inCorrectAnswerOverlay, toCompartmentalize, blankAnswerOverlay); return(toReturn); }
private void gradeSection(int sectionCode, Bitmap stretched, Sectionizer testSections, ExamSpecifics exam, double avRadius) { if (sectionCode == 0) { LineScannerSC prelines = new LineScannerSC(testSections.studentCondition, avRadius); StudentCondition section1 = new StudentCondition(prelines.lineX, prelines.lineY, stretched, exam, avRadius); section1.scoreSection(stretched); // should be in a worker thread scannedScores[sectionCode] = (section1); } if (sectionCode == 1) { LineScannerMC prelines = new LineScannerMC(testSections.multipleChoice, avRadius); Multiple_Choice section1 = new Multiple_Choice(prelines.lineX, prelines.lineY, stretched, exam, avRadius); section1.scoreSection(stretched); // should be in a worker thread scannedScores[sectionCode] = (section1); } else if (sectionCode == 2) { LineScannerPairing prelines = new LineScannerPairing(testSections.pairing, avRadius); Pairing section2 = new Pairing(prelines.lineX, prelines.lineY, stretched, exam, avRadius); section2.scoreSection(stretched); // should be in a worker thread scannedScores[sectionCode] = (section2); } else if (sectionCode == 3) { LineScannerTF prelines = new LineScannerTF(testSections.trueFalse, avRadius); True_False section3 = new True_False(prelines.lineX, prelines.lineY, stretched, exam, avRadius); section3.scoreSection(stretched); // should be in a worker thread scannedScores[sectionCode] = (section3); } else if (sectionCode == 4) { LineScannerCompletion prelines = new LineScannerCompletion(testSections.completion, avRadius); Completion section4 = new Completion(prelines.lineX, prelines.lineY, stretched, exam, avRadius); section4.scoreSection(stretched); // should be in a worker thread scannedScores[sectionCode] = (section4); } else if (sectionCode == 5) { LineScannerSubjective prelines = new LineScannerSubjective(testSections.subjective, avRadius); Subjective section4 = new Subjective(prelines.lineX, prelines.lineY, stretched, exam, avRadius); section4.scoreSection(stretched); // should be in a worker thread scannedScores[sectionCode] = (section4); } }
public ScanAndGrade(Bitmap stretched, Sectionizer testSections, ExamSpecifics exam, double avRadius) { Bitmap fullCopy1 = new Bitmap(stretched.Width, stretched.Height); Graphics g = Graphics.FromImage(fullCopy1); g.DrawImage(stretched, new Point(0, 0)); Bitmap fullCopy0 = new Bitmap(stretched.Width, stretched.Height); g = Graphics.FromImage(fullCopy0); g.DrawImage(stretched, new Point(0, 0)); Bitmap fullCopy2 = new Bitmap(stretched.Width, stretched.Height); g = Graphics.FromImage(fullCopy2); g.DrawImage(stretched, new Point(0, 0)); Bitmap fullCopy3 = new Bitmap(stretched.Width, stretched.Height); g = Graphics.FromImage(fullCopy3); g.DrawImage(stretched, new Point(0, 0)); Bitmap fullCopy4 = new Bitmap(stretched.Width, stretched.Height); g = Graphics.FromImage(fullCopy4); g.DrawImage(stretched, new Point(0, 0)); Bitmap fullCopy5 = new Bitmap(stretched.Width, stretched.Height); g = Graphics.FromImage(fullCopy5); g.DrawImage(stretched, new Point(0, 0)); g.Dispose(); scannedScores = new List <ExamSection>(5); scannedScores.Add(null); scannedScores.Add(null); scannedScores.Add(null); scannedScores.Add(null); scannedScores.Add(null); scannedScores.Add(null); Thread thread0 = new Thread(() => gradeSection(0, fullCopy0, testSections, exam, avRadius)); Thread thread1 = new Thread(() => gradeSection(1, fullCopy1, testSections, exam, avRadius)); Thread thread2 = new Thread(() => gradeSection(2, fullCopy2, testSections, exam, avRadius)); Thread thread3 = new Thread(() => gradeSection(3, fullCopy3, testSections, exam, avRadius)); Thread thread4 = new Thread(() => gradeSection(4, fullCopy4, testSections, exam, avRadius)); Thread thread5 = new Thread(() => gradeSection(5, fullCopy5, testSections, exam, avRadius)); thread0.Start(); thread1.Start(); thread2.Start(); thread3.Start(); thread4.Start(); thread5.Start(); thread1.Join(); thread2.Join(); thread3.Join(); thread0.Join(); thread4.Join(); thread5.Join(); for (int i = 0; i < scannedScores.Count; i++) { if (scannedScores[i] != null) { Debug.WriteLine(i + " : SCORE = " + scannedScores[i].score); FinalUnweightedScore = FinalUnweightedScore + scannedScores[i].score; } } }