示例#1
0
        private void buildAnalysisImage(Bitmap bitmapCamera)
        {
            bitmapAnalysis = (Bitmap)bitmapCamera.Clone();
            Graphics g = Graphics.FromImage(bitmapAnalysis);

            g.Clear(Color.Black);

            unsafe
            {
                BitmapData bitmapDataCamera   = null;
                BitmapData bitmapDataNormal   = null;
                BitmapData bitmapDataTrigger  = null;
                BitmapData bitmapDataAnalysis = null;
                try
                {
                    bitmapDataCamera   = bitmapCamera.LockBits(new Rectangle(0, 0, bitmapCamera.Width, bitmapCamera.Height), ImageLockMode.ReadOnly, bitmapCamera.PixelFormat);
                    bitmapDataNormal   = BitmapNormal.LockBits(new Rectangle(0, 0, BitmapNormal.Width, BitmapNormal.Height), ImageLockMode.ReadOnly, BitmapNormal.PixelFormat);
                    bitmapDataTrigger  = BitmapTrigger.LockBits(new Rectangle(0, 0, BitmapTrigger.Width, BitmapTrigger.Height), ImageLockMode.ReadOnly, BitmapTrigger.PixelFormat);
                    bitmapDataAnalysis = BitmapAnalysis.LockBits(new Rectangle(0, 0, BitmapTrigger.Width, BitmapTrigger.Height), ImageLockMode.WriteOnly, BitmapTrigger.PixelFormat);

                    int bytesPerPixel  = System.Drawing.Bitmap.GetPixelFormatSize(bitmapCamera.PixelFormat) / 8;
                    int heightInPixels = bitmapDataCamera.Height;
                    int widthInBytes   = bitmapDataCamera.Width * bytesPerPixel;

                    byte *PtrFirstPixel              = (byte *)bitmapDataCamera.Scan0;
                    byte *PtrFirstPixelNormal        = (byte *)bitmapDataNormal.Scan0;
                    byte *PtrFirstPixelTrigger       = (byte *)bitmapDataTrigger.Scan0;
                    byte *PtrFirstPixelAnalysisImage = (byte *)bitmapDataAnalysis.Scan0;

                    foreach (DetectionObject obj in detectionObjects)
                    {
                        int numPixels = obj.Rectangle.Width * obj.Rectangle.Height;
                        int step      = (numPixels / SamplesPerObject);
                        if (step == 0)
                        {
                            step = 1;
                        }
                        int   y             = obj.Rectangle.Top;
                        float maxDifference = (SamplesPerObject * bytesPerPixel * 256);

                        while (y < obj.Rectangle.Bottom)
                        {
                            byte *currentLine         = PtrFirstPixel + (y * bitmapDataCamera.Stride);
                            byte *currentLineNormal   = PtrFirstPixelNormal + (y * bitmapDataCamera.Stride);
                            byte *currentLineTrigger  = PtrFirstPixelTrigger + (y * bitmapDataCamera.Stride);
                            byte *currentLineAnalysis = PtrFirstPixelAnalysisImage + (y * bitmapDataAnalysis.Stride);

                            for (int x = obj.Rectangle.Left + (y % step); x < obj.Rectangle.Right; x += step)
                            {
                                int offsetX = x * bytesPerPixel;

                                int differenceNormal = Math.Abs(currentLine[offsetX] - currentLineNormal[offsetX]);
                                differenceNormal += Math.Abs(currentLine[offsetX + 1] - currentLineNormal[offsetX + 1]);
                                differenceNormal += Math.Abs(currentLine[offsetX + 2] - currentLineNormal[offsetX + 2]);

                                int differenceTrigger = Math.Abs(currentLine[offsetX] - currentLineTrigger[offsetX]);
                                differenceTrigger += Math.Abs(currentLine[offsetX + 1] - currentLineTrigger[offsetX + 1]);
                                differenceTrigger += Math.Abs(currentLine[offsetX + 2] - currentLineTrigger[offsetX + 2]);

                                if (differenceNormal < differenceTrigger)
                                {
                                    byte color = (byte)(255 - (differenceNormal / 3)); // difference is maximum 3*255 = 765. In that case outcome must be 255.
                                    currentLineAnalysis[offsetX + 1] = color;
                                }
                                else
                                {
                                    byte color = (byte)(255 - (differenceTrigger / 3)); // difference is maximum 3*255 = 765. In that case outcome must be 255.
                                    currentLineAnalysis[offsetX + 2] = color;
                                }
                            }
                            y++;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    bitmapCamera.UnlockBits(bitmapDataCamera);
                    bitmapNormal.UnlockBits(bitmapDataNormal);
                    bitmapTrigger.UnlockBits(bitmapDataTrigger);
                    bitmapAnalysis.UnlockBits(bitmapDataAnalysis);
                }
            }
        }
示例#2
0
        unsafe public void analyze(Bitmap bitmapCamera)
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();

            BitmapData bitmapDataCamera  = null;
            BitmapData bitmapDataNormal  = null;
            BitmapData bitmapDataTrigger = null;

            try
            {
                bitmapDataCamera  = bitmapCamera.LockBits(new Rectangle(0, 0, bitmapCamera.Width, bitmapCamera.Height), ImageLockMode.ReadOnly, bitmapCamera.PixelFormat);
                bitmapDataNormal  = BitmapNormal.LockBits(new Rectangle(0, 0, BitmapNormal.Width, BitmapNormal.Height), ImageLockMode.ReadOnly, BitmapNormal.PixelFormat);
                bitmapDataTrigger = BitmapTrigger.LockBits(new Rectangle(0, 0, BitmapTrigger.Width, BitmapTrigger.Height), ImageLockMode.ReadOnly, BitmapTrigger.PixelFormat);

                int bytesPerPixel  = System.Drawing.Bitmap.GetPixelFormatSize(bitmapCamera.PixelFormat) / 8;
                int heightInPixels = bitmapDataCamera.Height;
                int widthInBytes   = bitmapDataCamera.Width * bytesPerPixel;

                byte *PtrFirstPixel        = (byte *)bitmapDataCamera.Scan0;
                byte *PtrFirstPixelNormal  = (byte *)bitmapDataNormal.Scan0;
                byte *PtrFirstPixelTrigger = (byte *)bitmapDataTrigger.Scan0;

                foreach (DetectionObject obj in detectionObjects)
                {
                    if (!obj.Active)
                    {
                        continue;
                    }

                    int numPixels = obj.Rectangle.Width * obj.Rectangle.Height;     // TODO: make property of DetectionObject
                    int step      = (numPixels / SamplesPerObject);
                    if (step == 0)
                    {
                        step = 1;
                    }

                    int y = obj.Rectangle.Top;
                    int totalDifferenceNormal  = 0;
                    int totalDifferenceTrigger = 0;

                    float maxDifference = ((numPixels / step) * bytesPerPixel * 255);

                    while (y < obj.Rectangle.Bottom)
                    {
                        byte *currentLine         = PtrFirstPixel + (y * bitmapDataCamera.Stride);
                        byte *currentLineNormal   = PtrFirstPixelNormal + (y * bitmapDataCamera.Stride);
                        byte *currentLineTrigger  = PtrFirstPixelTrigger + (y * bitmapDataCamera.Stride);
                        byte *currentLineAnalysis = null;

                        for (int x = obj.Rectangle.Left + (y % step); x < obj.Rectangle.Right; x += step)
                        {
                            int offsetX = x * bytesPerPixel;

/*
 *                          totalDifferenceNormal += Math.Abs(currentLine[offsetX] - currentLineNormal[offsetX]);
 *                          totalDifferenceNormal += Math.Abs(currentLine[offsetX + 1] - currentLineNormal[offsetX + 1]);
 *                          totalDifferenceNormal += Math.Abs(currentLine[offsetX + 2] - currentLineNormal[offsetX + 2]);
 */
                            totalDifferenceTrigger += Math.Abs(currentLine[offsetX] - currentLineTrigger[offsetX]);
                            totalDifferenceTrigger += Math.Abs(currentLine[offsetX + 1] - currentLineTrigger[offsetX + 1]);
                            totalDifferenceTrigger += Math.Abs(currentLine[offsetX + 2] - currentLineTrigger[offsetX + 2]);
                        }
                        y++;
                    }

                    obj.DifferenceNormal = totalDifferenceNormal / maxDifference;

                    float numSamples = numPixels / step;

                    // When the difference is small enough, we make further investigation

/*                    if (obj.DifferenceNormal < 0.05)
 *                  {
 *                      obj.SecondLevelDifferenceNormal = secondLevelAnalysis(bitmapDataCamera, bitmapDataNormal, obj, step, bytesPerPixel) / numSamples;
 *                  }
 */
                    obj.DifferenceTrigger = totalDifferenceTrigger / maxDifference;
                    // When the difference is small enough, we make further investigation
                    if (obj.DifferenceTrigger < 0.05)
                    {
                        obj.SecondLevelDifferenceTrigger = secondLevelAnalysis(bitmapDataCamera, bitmapDataTrigger, obj, step, bytesPerPixel) / numSamples;
                    }
                    obj.updateStatus();
                }
            } catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                bitmapCamera.UnlockBits(bitmapDataCamera);
                bitmapNormal.UnlockBits(bitmapDataNormal);
                bitmapTrigger.UnlockBits(bitmapDataTrigger);
            }

            watch.Stop();
            analysisTime = watch.ElapsedMilliseconds;

            if (makeAnalysisImage)
            {
                buildAnalysisImage(bitmapCamera);
            }
        }