public override void DoWork() { TestExecution().LogMessageWithTimeFromTrigger(Name + " started"); Stopwatch watch = new Stopwatch(); watch.Start(); long numPixels = 0; int H_current; double H_avg = -1; int H_min = 999999; int H_max = -999999; double H_stddev = -1; long H_sum = 0; int S_current; double S_avg = -1; int S_min = 999999; int S_max = -999999; double S_stddev = -1; long S_sum = 0; int I_current; double I_avg = -1; int I_min = 999999; int I_max = -999999; double I_stddev = -1; long I_sum = 0; int R_current; double R_avg = -1; int R_min = 999999; int R_max = -999999; double R_stddev = -1; long R_sum = 0; int G_current; double G_avg = -1; int G_min = 999999; int G_max = -999999; double G_stddev = -1; long G_sum = 0; int B_current; double B_avg = -1; int B_min = 999999; int B_max = -999999; double B_stddev = -1; long B_sum = 0; int Grey_current; double Grey_avg = -1; int Grey_min = 999999; int Grey_max = -999999; double Grey_stddev = -1; long Grey_sum = 0; if (mPrerequisite != null && !mPrerequisite.ValueAsBoolean()) { TestExecution().LogMessageWithTimeFromTrigger(Name + ": prerequisites not met. Skipping."); } else { if (true) { if (mSourceImage != null && mSourceImage.Bitmap != null) { Point currentPoint = new Point(-1, -1); mROI.GetFirstPointOnXAxis(mSourceImage, ref currentPoint); Color color; while (currentPoint.X > -1 && currentPoint.Y > -1) { numPixels++; color = mSourceImage.GetColor(currentPoint.X, currentPoint.Y); H_current = (int)(color.GetHue()); S_current = (int)(color.GetSaturation() * 100); I_current = (int)(color.GetBrightness() * 100); Grey_current = (int)(0.3 * color.R + 0.59 * color.G + 0.11 * color.B); // Then, add 30% of the red value, 59% of the green value, and 11% of the blue value, together. .... These percentages are chosen due to the different relative sensitivity of the normal human eye to each of the primary colors (less sensitive to green, more to blue). R_current = color.R; G_current = color.G; B_current = color.B; H_sum += H_current; if (H_current < H_min) { H_min = H_current; } if (H_current > H_max) { H_max = H_current; } S_sum += S_current; if (S_current < S_min) { S_min = S_current; } if (S_current > S_max) { S_max = S_current; } I_sum += I_current; if (I_current < I_min) { I_min = I_current; } if (I_current > I_max) { I_max = I_current; } R_sum += R_current; if (R_current < R_min) { R_min = R_current; } if (R_current > R_max) { R_max = R_current; } G_sum += G_current; if (G_current < G_min) { G_min = G_current; } if (G_current > G_max) { G_max = G_current; } B_sum += B_current; if (B_current < B_min) { B_min = B_current; } if (B_current > B_max) { B_max = B_current; } Grey_sum += Grey_current; if (Grey_current < Grey_min) { Grey_min = Grey_current; } if (Grey_current > Grey_max) { Grey_max = Grey_current; } mROI.GetNextPointOnXAxis(mSourceImage, ref currentPoint); } if (numPixels > 0) { H_avg = ((double)H_sum) / numPixels; S_avg = ((double)S_sum) / numPixels; I_avg = ((double)I_sum) / numPixels; R_avg = ((double)R_sum) / numPixels; G_avg = ((double)G_sum) / numPixels; B_avg = ((double)B_sum) / numPixels; Grey_avg = ((double)Grey_sum) / numPixels; } else { TestExecution().LogErrorWithTimeFromTrigger("ColorAnalysis " + Name + " didn't analyze any pixels -- check ROI size."); } } // if image not null } else // if not new array pixel access, then use old pointer access { Bitmap sourceBitmap = SourceImage.Bitmap; if (sourceBitmap != null) { // for LockBits see http://www.bobpowell.net/lockingbits.htm & http://www.codeproject.com/csharp/quickgrayscale.asp?df=100&forumid=293759&select=2214623&msg=2214623 BitmapData sourceBitmapData = null; try { sourceBitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); const int pixelByteWidth = 4; // determined by PixelFormat.Format32bppArgb int stride = sourceBitmapData.Stride; int strideOffset = stride - (sourceBitmapData.Width * pixelByteWidth); Point currentPoint = new Point(-1, -1); mROI.GetFirstPointOnXAxis(mSourceImage, ref currentPoint); unsafe // see http://www.codeproject.com/csharp/quickgrayscale.asp?df=100&forumid=293759&select=2214623&msg=2214623 { byte *sourcePointer; Color color; while (currentPoint.X > -1 && currentPoint.Y > -1) { numPixels++; sourcePointer = (byte *)sourceBitmapData.Scan0; // init to first byte of image sourcePointer += (currentPoint.Y * stride) + (currentPoint.X * pixelByteWidth); // adjust to current point color = Color.FromArgb(sourcePointer[3], sourcePointer[2], sourcePointer[1], sourcePointer[0]); // Array index 0 is blue, 1 is green, 2 is red, 0 is alpha H_current = (int)(color.GetHue()); S_current = (int)(color.GetSaturation() * 100); I_current = (int)(color.GetBrightness() * 100); Grey_current = (int)(0.3 * color.R + 0.59 * color.G + 0.11 * color.B); // Then, add 30% of the red value, 59% of the green value, and 11% of the blue value, together. .... These percentages are chosen due to the different relative sensitivity of the normal human eye to each of the primary colors (less sensitive to green, more to blue). R_current = color.R; G_current = color.G; B_current = color.B; H_sum += H_current; if (H_current < H_min) { H_min = H_current; } if (H_current > H_max) { H_max = H_current; } S_sum += S_current; if (S_current < S_min) { S_min = S_current; } if (S_current > S_max) { S_max = S_current; } I_sum += I_current; if (I_current < I_min) { I_min = I_current; } if (I_current > I_max) { I_max = I_current; } R_sum += R_current; if (R_current < R_min) { R_min = R_current; } if (R_current > R_max) { R_max = R_current; } G_sum += G_current; if (G_current < G_min) { G_min = G_current; } if (G_current > G_max) { G_max = G_current; } B_sum += B_current; if (B_current < B_min) { B_min = B_current; } if (B_current > B_max) { B_max = B_current; } Grey_sum += Grey_current; if (Grey_current < Grey_min) { Grey_min = Grey_current; } if (Grey_current > Grey_max) { Grey_max = Grey_current; } mROI.GetNextPointOnXAxis(mSourceImage, ref currentPoint); } if (numPixels > 0) { H_avg = ((double)H_sum) / numPixels; S_avg = ((double)S_sum) / numPixels; I_avg = ((double)I_sum) / numPixels; R_avg = ((double)R_sum) / numPixels; G_avg = ((double)G_sum) / numPixels; B_avg = ((double)B_sum) / numPixels; Grey_avg = ((double)Grey_sum) / numPixels; } else { TestExecution().LogErrorWithTimeFromTrigger("ColorAnalysis " + Name + " didn't analyze any pixels -- check ROI size."); } } // end unsafe block } finally { sourceBitmap.UnlockBits(sourceBitmapData); } } // if bitmap } // pixel access type } // if prereqs met if (mH_Average != null) { mH_Average.SetValue(H_avg); mH_Average.SetIsComplete(); } if (mH_Min != null) { mH_Min.SetValue(H_min); mH_Min.SetIsComplete(); } if (mH_Max != null) { mH_Max.SetValue(H_max); mH_Max.SetIsComplete(); } if (mH_StdDev != null) { mH_StdDev.SetValue(H_stddev); mH_StdDev.SetIsComplete(); } if (mS_Average != null) { mS_Average.SetValue(S_avg); mS_Average.SetIsComplete(); } if (mS_Min != null) { mS_Min.SetValue(S_min); mS_Min.SetIsComplete(); } if (mS_Max != null) { mS_Max.SetValue(S_max); mS_Max.SetIsComplete(); } if (mS_StdDev != null) { mS_StdDev.SetValue(S_stddev); mS_StdDev.SetIsComplete(); } if (mI_Average != null) { mI_Average.SetValue(I_avg); mI_Average.SetIsComplete(); } if (mI_Min != null) { mI_Min.SetValue(I_min); mI_Min.SetIsComplete(); } if (mI_Max != null) { mI_Max.SetValue(I_max); mI_Max.SetIsComplete(); } if (mI_StdDev != null) { mI_StdDev.SetValue(I_stddev); mI_StdDev.SetIsComplete(); } if (mR_Average != null) { mR_Average.SetValue(R_avg); mR_Average.SetIsComplete(); } if (mR_Min != null) { mR_Min.SetValue(R_min); mR_Min.SetIsComplete(); } if (mR_Max != null) { mR_Max.SetValue(R_max); mR_Max.SetIsComplete(); } if (mR_StdDev != null) { mR_StdDev.SetValue(R_stddev); mR_StdDev.SetIsComplete(); } if (mG_Average != null) { mG_Average.SetValue(G_avg); mG_Average.SetIsComplete(); } if (mG_Min != null) { mG_Min.SetValue(G_min); mG_Min.SetIsComplete(); } if (mG_Max != null) { mG_Max.SetValue(G_max); mG_Max.SetIsComplete(); } if (mG_StdDev != null) { mG_StdDev.SetValue(G_stddev); mG_StdDev.SetIsComplete(); } if (mB_Average != null) { mB_Average.SetValue(B_avg); mB_Average.SetIsComplete(); } if (mB_Min != null) { mB_Min.SetValue(B_min); mB_Min.SetIsComplete(); } if (mB_Max != null) { mB_Max.SetValue(B_max); mB_Max.SetIsComplete(); } if (mB_StdDev != null) { mB_StdDev.SetValue(B_stddev); mB_StdDev.SetIsComplete(); } if (mGrey_Average != null) { mGrey_Average.SetValue(Grey_avg); mGrey_Average.SetIsComplete(); } if (mGrey_Min != null) { mGrey_Min.SetValue(Grey_min); mGrey_Min.SetIsComplete(); } if (mGrey_Max != null) { mGrey_Max.SetValue(Grey_max); mGrey_Max.SetIsComplete(); } if (mGrey_StdDev != null) { mGrey_StdDev.SetValue(Grey_stddev); mGrey_StdDev.SetIsComplete(); } mIsComplete = true; watch.Stop(); TestExecution().LogMessageWithTimeFromTrigger(Name + " took " + watch.ElapsedMilliseconds + "ms (" + watch.ElapsedTicks + " ticks for " + numPixels + " pixels)"); }
public override void DoWork() { // NOTE: this code was adapted from FindObjectCenterOnLine; one difference is that it searched until it found the object, then quit. We search the entire path DateTime startTime = DateTime.Now; TestExecution().LogMessageWithTimeFromTrigger("[" + Name + "] started at " + startTime + Environment.NewLine); int resultX = -1; int resultY = -1; if (mSourceImage.Bitmap == null) { TestExecution().LogErrorWithTimeFromTrigger("source image for '" + Name + "' does not exist."); } else if (mSearchPath == null) { TestExecution().LogErrorWithTimeFromTrigger("search line for '" + Name + "' isn't defined."); } else if (mSearchPath.StartX == null || mSearchPath.StartY == null || mSearchPath.EndX == null || mSearchPath.EndY == null) { TestExecution().LogErrorWithTimeFromTrigger("search line '" + mSearchPath.Name + "' for '" + Name + "' isn't fully defined."); } else if (mSearchPath.StartX.ValueAsLong() < 0 || mSearchPath.StartX.ValueAsLong() >= mSourceImage.Bitmap.Width || mSearchPath.StartY.ValueAsLong() < 0 || mSearchPath.StartY.ValueAsLong() >= mSourceImage.Bitmap.Height) { TestExecution().LogErrorWithTimeFromTrigger("The search line start point for '" + Name + "' isn't valid: " + mSearchPath.StartX.ValueAsLong() + "," + mSearchPath.StartY.ValueAsLong()); } else if (mSearchPath.EndX.ValueAsLong() < 0 || mSearchPath.EndX.ValueAsLong() >= mSourceImage.Bitmap.Width || mSearchPath.EndY.ValueAsLong() < 0 || mSearchPath.EndY.ValueAsLong() >= mSourceImage.Bitmap.Height) { TestExecution().LogErrorWithTimeFromTrigger("The search line end point for '" + Name + "' isn't valid: " + mSearchPath.EndX.ValueAsLong() + "," + mSearchPath.EndY.ValueAsLong()); } else if (Math.Abs(mSearchPath.StartX.ValueAsLong() - mSearchPath.EndX.ValueAsLong()) < 1 && Math.Abs(mSearchPath.StartY.ValueAsLong() - mSearchPath.EndY.ValueAsLong()) < 1) { TestExecution().LogErrorWithTimeFromTrigger("Search path is too small."); } else { long width = Math.Abs(mSearchPath.StartX.ValueAsLong() - mSearchPath.EndX.ValueAsLong()) + 1; long height = Math.Abs(mSearchPath.StartY.ValueAsLong() - mSearchPath.EndY.ValueAsLong()) + 1; double run; double rise; double angle; double sineOfAngle = -1; double cosineOfAngle = -1; LineType lineType; long length; startX = mSearchPath.StartX.ValueAsLong(); startY = mSearchPath.StartY.ValueAsLong(); endX = mSearchPath.EndX.ValueAsLong(); endY = mSearchPath.EndY.ValueAsLong(); if (mSearchPath.StartY.ValueAsLong() == mSearchPath.EndY.ValueAsLong()) // if it is horizonal line (no Y deviation) { lineType = LineType.Horizontal; length = width; ySearchChange = 0; if (mSearchPath.StartX.ValueAsLong() < mSearchPath.EndX.ValueAsLong()) { xSearchChange = 1; } else { xSearchChange = -1; } } else if (mSearchPath.StartX.ValueAsLong() == mSearchPath.EndX.ValueAsLong()) // if it is vertical line (no X deviation) { lineType = LineType.Vertical; length = height; xSearchChange = 0; if (mSearchPath.StartY.ValueAsLong() < mSearchPath.EndY.ValueAsLong()) // line is down { ySearchChange = 1; } else // line is up { ySearchChange = -1; } } else // slanted line { run = mSearchPath.EndX.ValueAsLong() - mSearchPath.StartX.ValueAsLong(); rise = mSearchPath.EndY.ValueAsLong() - mSearchPath.StartY.ValueAsLong(); angle = Math.Atan(rise / run); sineOfAngle = Math.Sin(angle); cosineOfAngle = Math.Cos(angle); lineType = LineType.Slanted; length = (long)Math.Sqrt(height * height + width * width); } leftEdgeOfSearch = Math.Max(0, Math.Min(startX, endX)); rightEdgeOfSearch = Math.Min(mSourceImage.Bitmap.Width, Math.Max(startX, endX)); topEdgeOfSearch = Math.Max(0, Math.Min(startY, endY)); bottomEdgeOfSearch = Math.Min(mSourceImage.Bitmap.Height, Math.Max(startY, endY)); x = (int)startX; y = (int)startY; TestExecution().LogMessage(Name + " starting at " + x + "," + y); abort = false; Point firstPoint = new Point(-1, -1); Point lastPoint = new Point(-1, -1); for (int searchIndex = 0; searchIndex <= length && !abort; searchIndex++) { switch (lineType) { case LineType.Horizontal: x = (int)(startX + (searchIndex * xSearchChange)); break; case LineType.Vertical: y = (int)(startY + (searchIndex * ySearchChange)); break; case LineType.Slanted: x = (int)(startX + Math.Round(searchIndex * cosineOfAngle)); y = (int)(startY + Math.Round(searchIndex * sineOfAngle)); break; } if (x < leftEdgeOfSearch || x > rightEdgeOfSearch || y < topEdgeOfSearch || y > bottomEdgeOfSearch) { TestExecution().LogErrorWithTimeFromTrigger(Name + " aborting at " + x + "," + y + ". Out of range from path for some reason."); abort = true; } else { pixelColor = mSourceImage.GetColor(x, y); if (mSearchColorDefinition.Matches(pixelColor)) { TestExecution().LogMessage(Name + " found color match at " + x + "," + y); if (firstPoint.X < 0) { firstPoint.X = x; firstPoint.Y = y; } lastPoint.X = x; lastPoint.Y = y; } else { //mSourceImage.SetColor(x, y, Color.Lime); //TestExecution().LogMessage(Name + " " + x + "," + y + " is not a match"); } } // end if for x,y verification } // end search loop resultX = (firstPoint.X + lastPoint.X) / 2; resultY = (firstPoint.Y + lastPoint.Y) / 2; } // end main block ("else" after all initial setup error checks) mResultX.SetValue(resultX); mResultY.SetValue(resultY); mResultX.SetIsComplete(); mResultY.SetIsComplete(); DateTime doneTime = DateTime.Now; TimeSpan computeTime = doneTime - startTime; TestExecution().LogMessage(Name + " computed object center at " + resultX + "," + resultY); TestExecution().LogMessageWithTimeFromTrigger(Name + " finished at " + doneTime + " | took " + computeTime.TotalMilliseconds + "ms"); }
public override bool ContainsPoint(ImageInstance theImage, System.Drawing.Point thePoint) { return(mMainROI.ContainsPoint(theImage, thePoint) && !mColorException.Matches(theImage.GetColor(thePoint.X, thePoint.Y))); }
// public const string AnalysisType = "Color Present Fails"; // public override string Type() { return AnalysisType; } public override void DoWork() { TestExecution().LogMessageWithTimeFromTrigger("ColorMatchCount " + Name + " started"); DateTime startTime = DateTime.Now; mMatchCount = 0; if (mSourceImage.Bitmap != null) { if (true) { Point currentPoint = new Point(-1, -1); mROI.GetFirstPointOnXAxis(mSourceImage, ref currentPoint); Color color; while (currentPoint.X != -1 && currentPoint.Y != -1) { color = mSourceImage.GetColor(currentPoint.X, currentPoint.Y); if (mColorMatcher.Matches(color)) { mMatchCount++; if (mImageToMark != null && mImageToMark.Bitmap != null) { mImageToMark.SetColor(currentPoint.X, currentPoint.Y, mMarkColor); } } mROI.GetNextPointOnXAxis(mSourceImage, ref currentPoint); } } else { Bitmap sourceBitmap = SourceImage.Bitmap; Bitmap markedBitmap = null; if (mCreateMarkedImage && mImageToMark != null && mImageToMark.Bitmap != null) { markedBitmap = mImageToMark.Bitmap; } // for LockBits see http://www.bobpowell.net/lockingbits.htm & http://www.codeproject.com/csharp/quickgrayscale.asp?df=100&forumid=293759&select=2214623&msg=2214623 BitmapData sourceBitmapData = null; BitmapData markedBitmapData = null; try { sourceBitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); if (markedBitmap != null) { markedBitmapData = markedBitmap.LockBits(new Rectangle(0, 0, markedBitmap.Width, markedBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); } const int pixelByteWidth = 4; // determined by PixelFormat.Format32bppArgb int stride = sourceBitmapData.Stride; int strideOffset = stride - (sourceBitmapData.Width * pixelByteWidth); Point currentPoint = new Point(-1, -1); mROI.GetFirstPointOnXAxis(mSourceImage, ref currentPoint); unsafe // see http://www.codeproject.com/csharp/quickgrayscale.asp?df=100&forumid=293759&select=2214623&msg=2214623 { byte *sourcePointer; byte *markedPointer; Color color; while (currentPoint.X != -1 && currentPoint.Y != -1) { sourcePointer = (byte *)sourceBitmapData.Scan0; // init to first byte of image sourcePointer += (currentPoint.Y * stride) + (currentPoint.X * pixelByteWidth); // adjust to current point color = Color.FromArgb(sourcePointer[3], sourcePointer[2], sourcePointer[1], sourcePointer[0]); // Array index 0 is blue, 1 is green, 2 is red, 0 is alpha if (mColorMatcher.Matches(color)) { mMatchCount++; if (markedBitmap != null) { markedPointer = (byte *)markedBitmapData.Scan0; markedPointer += (currentPoint.Y * stride) + (currentPoint.X * pixelByteWidth); markedPointer[3] = mMarkColor.A; markedPointer[2] = mMarkColor.R; markedPointer[1] = mMarkColor.G; markedPointer[0] = mMarkColor.B; } } mROI.GetNextPointOnXAxis(mSourceImage, ref currentPoint); } } // end unsafe block } finally { sourceBitmap.UnlockBits(sourceBitmapData); if (markedBitmap != null) { markedBitmap.UnlockBits(markedBitmapData); } } } } mResult.SetValue(mMatchCount); mResult.SetIsComplete(); DateTime doneTime = DateTime.Now; TimeSpan computeTime = doneTime - startTime; TestExecution().LogMessageWithTimeFromTrigger(Name + " took " + computeTime.TotalMilliseconds + "ms"); //MessageBox.Show("done in color count for " + Name); }
public override System.Drawing.Point GetNextPointOnYAxis(ImageInstance theImage, ref System.Drawing.Point theNextPoint) { do { mMainROI.GetNextPointOnYAxis(theImage, ref theNextPoint); } while (theNextPoint.X != -1 && theNextPoint.Y != -1 && mColorException.Matches(theImage.GetColor(theNextPoint.X, theNextPoint.Y))); return(theNextPoint); }