protected override void DoCompareFrames(FrameTransition transition) { RGBData frame1 = transition.Frame1; RGBData frame2 = transition.Frame2; int index = transition.Index; if (outputImageData == null) { outputImageData = new ImageData(new Bitmap(frames, frame1.Rows * 3)); outputImageData.Lock(); } for (int i = 0; i < frame1.Rows; i++) { outputImageData.Data.SetR(counter, i, frame1.GetR(frame1.Columns / 4, i)); outputImageData.Data.SetG(counter, i, frame1.GetG(frame1.Columns / 4, i)); outputImageData.Data.SetB(counter, i, frame1.GetB(frame1.Columns / 4, i)); outputImageData.Data.SetR(counter, i + frame1.Rows, frame1.GetR(frame1.Columns / 2, i)); outputImageData.Data.SetG(counter, i + frame1.Rows, frame1.GetG(frame1.Columns / 2, i)); outputImageData.Data.SetB(counter, i + frame1.Rows, frame1.GetB(frame1.Columns / 2, i)); outputImageData.Data.SetR(counter, i + frame1.Rows * 2, frame1.GetR(frame1.Columns * 3 / 4, i)); outputImageData.Data.SetG(counter, i + frame1.Rows * 2, frame1.GetG(frame1.Columns * 3 / 4, i)); outputImageData.Data.SetB(counter, i + frame1.Rows * 2, frame1.GetB(frame1.Columns * 3 / 4, i)); } }
/// <summary> /// Draw the given image on this image. /// </summary> /// <param name="srcData">The image to draw</param> /// <param name="destX">The X position on this image.</param> /// <param name="destY">The Y position on this image.</param> /// <param name="srcX">The X position on the source image.</param> /// <param name="srcY">The Y position on the source image.</param> /// <param name="srcWidth">The width of the source image to draw.</param> /// <param name="srcHeight">The height of the source image to draw.</param> public void Draw(RGBData srcData, int destX, int destY, int srcX, int srcY, int srcWidth, int srcHeight) { for (int j = 0; j < srcHeight - srcY; j++) { for (int i = 0; i < srcWidth - srcX; i++) { Data.SetR(destX + i, destY + j, srcData.GetR(i + srcX, j + srcY)); Data.SetG(destX + i, destY + j, srcData.GetG(i + srcX, j + srcY)); Data.SetB(destX + i, destY + j, srcData.GetB(i + srcX, j + srcY)); } } }
/// <summary> /// Scales the pixel values of the image. /// </summary> /// <param name="xScale">The value by which to scale x.</param> /// <param name="yScale">The value by which to scale y.</param> /// <returns></returns> public RGBData Scale(double xScale, double yScale) { if (xScale < 0.0001) { xScale = 0.0001; } if (yScale < 0.0001) { yScale = 0.0001; } double xPixels = 1 / xScale; double yPixels = 1 / yScale; double xFraction = xPixels - (int)xPixels; double yFraction = yPixels - (int)yPixels; int scaledColumns = (int)(Data.Columns * xScale); int scaledRows = (int)(Data.Rows * yScale); int scaledStride = scaledColumns * 3; RGBData data = new RGBData(new byte[scaledStride * scaledRows], scaledStride); for (int row = 0; row < scaledRows; row++) { for (int col = 0; col < scaledColumns; col++) { double rSum = 0; double gSum = 0; double bSum = 0; int xPos = (int)(col * xPixels); int yPos = (int)(row * yPixels); for (int i = 0; i < (int)yPixels; i++) { for (int j = 0; j < (int)xPixels; j++) { rSum += Data.GetR(xPos + j, yPos + i); gSum += Data.GetG(xPos + j, yPos + i); bSum += Data.GetB(xPos + j, yPos + i); } } data.SetR(col, row, (byte)(rSum / (int)((int)xPixels * (int)yPixels))); data.SetG(col, row, (byte)(gSum / (int)((int)xPixels * (int)yPixels))); data.SetB(col, row, (byte)(bSum / (int)((int)xPixels * (int)yPixels))); } } return(data); }
/// <summary> /// Locks the Bitmap for editing and copies the bytes into data allowing /// them to be modified. /// </summary> public void Lock() { if (!IsLocked) { BitmapData = Image.LockBits(new Rectangle(0, 0, Image.Width, Image.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); int numBytes = BitmapData.Stride * Image.Height; Data = new RGBData(new byte[numBytes], BitmapData.Stride); Marshal.Copy(BitmapData.Scan0, Data.RGB, 0, numBytes); IsLocked = true; } }
protected override void DoCompareFrames(FrameTransition frameTransition) { RGBData frame1 = frameTransition.Frame1; RGBData frame2 = frameTransition.Frame2; int index = frameTransition.Index; double sum = 0; for (int row = 0; row < frame1.Rows; row++) { for (int col = 0; col < frame1.Columns; col++) { double i1 = rFactor * frame1.GetR(col, row) + gFactor * frame1.GetG(col, row) + bFactor * frame1.GetB(col, row); sum += i1; } } result[index] = sum / (frame1.Columns * frame1.Rows); }
public Task <double[]> Calculate(IVideoData data) { Func <double[]> func = () => { frameCount = data.FrameCount; DoInitialize(frameCount); completed = 0; maxFrameLock = new Semaphore(maxOpenFrames, maxOpenFrames); completeLock = new Semaphore(1, 1); completeLock.WaitOne(); data.CurrentFrame = 0; RGBData frame1 = null; ImageData data1 = data.GetNextFrame(); if (data1 != null) { data1.Lock(); frame1 = data1.Data; } RGBData frame2 = null; ImageData data2 = data.GetNextFrame(); if (data2 != null) { data2.Lock(); frame2 = data2.Data; } int counter = 0; while (data2 != null) { maxFrameLock.WaitOne(); FrameTransition frameTransition = new FrameTransition(frame1, frame2, counter++); ThreadPool.QueueUserWorkItem(new WaitCallback((state) => { DoCompareFrames(frameTransition); maxFrameLock.Release(); Interlocked.Increment(ref completed); if (completed >= frameCount - 1) { completeLock.Release(); } })); frame1 = frame2; data2 = data.GetNextFrame(); if (data2 != null) { data2.Lock(); frame2 = data2.Data; } } completeLock.WaitOne(); double[] results = DoComputeData(); completeLock.Release(); return(results); }; return(Task <double[]> .Run(func)); }
public FrameTransition(RGBData frame1, RGBData frame2, int index) { Frame1 = frame1; Frame2 = frame2; Index = index; }
protected override void DoCompareFrames(FrameTransition transition) { RGBData frame1 = transition.Frame1; RGBData frame2 = transition.Frame2; int index = transition.Index; int[,,,,] histogram1 = new int[areas, areas, buckets, buckets, buckets]; int[,,,,] histogram2 = new int[areas, areas, buckets, buckets, buckets]; int factor = 256 / buckets; double colSize = frame1.Columns / (double)areas; double rowSize = frame2.Rows / (double)areas; for (int row = 0; row < frame1.Rows; row++) { for (int col = 0; col < frame1.Columns; col++) { int r1 = frame1.GetR(col, row); int g1 = frame1.GetG(col, row); int b1 = frame1.GetB(col, row); histogram1[(int)(col / colSize), (int)(row / rowSize), r1 / factor, g1 / factor, b1 / factor]++; int r2 = frame2.GetR(col, row); int g2 = frame2.GetG(col, row); int b2 = frame2.GetB(col, row); histogram2[(int)(col / colSize), (int)(row / rowSize), r2 / factor, g2 / factor, b2 / factor]++; } } List <int> sums = new List <int>(); for (int row = 0; row < areas; row++) { for (int col = 0; col < areas; col++) { int sum = 0; for (int k = 0; k < buckets; k++) { for (int j = 0; j < buckets; j++) { for (int i = 0; i < buckets; i++) { sum += Math.Abs(histogram1[col, row, i, j, k] - histogram2[col, row, i, j, k]); } } } sums.Add(sum); } } int removeCount = (int)(sums.Count * percentRemove); if (removeCount > 0) { sums = sums.OrderBy(s => s).ToList(); for (int i = 0; i < removeCount; i++) { sums.RemoveAt(sums.Count - 1); } } double max = frame1.Columns * frame1.Rows * 2 - (colSize * rowSize * removeCount); result[index] = sums.Sum() / max; }
/// <summary> /// Draw the given image on this image. /// </summary> /// <param name="srcData">The image to draw</param> /// <param name="destX">The X position on this image.</param> /// <param name="destY">The Y position on this image.</param> public void Draw(RGBData srcData, int destX, int destY) { Draw(srcData, destX, destY, 0, 0, srcData.Columns, srcData.Rows); }