public YDataFloat GetFloatData() { if (_floatData == null) { lock (_floatDataLock) { if (_floatData == null) { var floatArray = new float[Width, Height]; int height = Height; unsafe { //for (int y = 0; y < Height; y++) Parallel.For(0, height, (y) => { fixed(byte *pData = Data) { fixed(float *pFloat = floatArray) { int *pDataInt = (int *)pData; int ySrcOffset = (y * Stride) / sizeof(int); int xMax = Width / 2; int yDstOffset = y; int x = 0; while (x < xMax) { int color1, color2, color3, color4; int color = pDataInt[ySrcOffset++]; color1 = (color & 0xFF); color2 = (color >> 8) & 0xFF; color3 = (color >> 16) & 0xFF; color4 = (color >> 24) & 0xFF; pFloat[yDstOffset] = color1; yDstOffset += height; pFloat[yDstOffset] = color2; yDstOffset += height; pFloat[yDstOffset] = color3; yDstOffset += height; pFloat[yDstOffset] = color4; yDstOffset += height; x += 2; } } } }); } _floatData = new YDataFloat(floatArray, byte.MaxValue); } } } return(_floatData); }
// -------------- Frame difference, for logo detection -------------- public static void CalculateLogoDifference(YDataFloat edgeMapAvg, YDataFloat logoDetectionFrame, float detectionFrameAverage, float detectionFrameMaximum, out float difference) { int width = edgeMapAvg.Width; int height = edgeMapAvg.Height; var detectionFrameMaximumOffset = (detectionFrameMaximum - detectionFrameAverage); // Calculate absolute difference between values and apply power of important pixels from logoDetectionFrame var total = 0.0f; unsafe { fixed(float *pEdgeMapAvg = edgeMapAvg.Data, pLogoDetectionFrame = logoDetectionFrame.Data) { int size = width * height; for (int i = 0; i < size; i++) { var detectionFrameOffset = Math.Abs(pLogoDetectionFrame[i] - detectionFrameAverage); var edgeMapOffset = Math.Abs(pEdgeMapAvg[i] - detectionFrameAverage); if (edgeMapOffset < detectionFrameOffset) { var power = detectionFrameOffset / detectionFrameMaximumOffset; total += power * (detectionFrameOffset - edgeMapOffset) * 255.0f / detectionFrameMaximumOffset; } } } } total /= (float)(width * height); difference = total; }
public static YDataFloat GenerateEdgeDetectedImage(YDataFloat imageData) { var width = imageData.Width; var height = imageData.Height; var edgeData = new float[width, height]; Parallel.For(0, height, (y) => { for (int x = 0; x < width; x++) { if ((y < height - 1) && (x < width - 1)) { edgeData[x, y] = imageData.Data[x + 1, y] + imageData.Data[x, y + 1] - imageData.Data[x, y] - imageData.Data[x, y]; edgeData[x, y] /= 2.0f; edgeData[x, y] += (imageData.MaximumValue / 2.0f); if (edgeData[x, y] < 0.0f) { edgeData[x, y] = 0.0f; } if (edgeData[x, y] > imageData.MaximumValue) { edgeData[x, y] = imageData.MaximumValue; } } else { edgeData[x, y] = 127.5f; // byte.MaxValue / 2.0f; } } }); return(new YDataFloat(edgeData, imageData.MaximumValue)); }
// -------------- Edge detection -------------- //"02.6656726 - Edge Detect CPU Single Threaded //"01.1025473 - Edge Detect CPU Parallel //"02.1731188 - Edge Detect Accel Multicore //"00.7777913 - Edge Detect Accel DX9 public static YDataFloat GenerateEdgeDetectedImageSingleThreaded(YDataFloat imageData) { var width = imageData.Width; var height = imageData.Height; var edgeData = new float[width, height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if ((y < height - 1) && (x < width - 1)) { edgeData[x, y] = imageData.Data[x + 1, y] + imageData.Data[x, y + 1] - imageData.Data[x, y] - imageData.Data[x, y]; edgeData[x, y] /= 2.0f; edgeData[x, y] += (imageData.MaximumValue / 2.0f); if (edgeData[x, y] < 0.0f) { edgeData[x, y] = 0.0f; } if (edgeData[x, y] > imageData.MaximumValue) { edgeData[x, y] = imageData.MaximumValue; } } else { edgeData[x, y] = 0.0f; } } } return(new YDataFloat(edgeData, imageData.MaximumValue)); }
public static void CalculateStandardDeviationCPU(YDataFloat imageData, float average, out float stdDev) { int width = imageData.Width; int height = imageData.Height; // Calculate standard deviation stdDev = 0.0f; float[] totalSlices = new float[height]; Parallel.For(0, height, (y) => { unsafe { fixed(float *pFloat = imageData.Data) { int ySrcOffset = y; float total = 0.0f; for (int x = 0; x < width; x++) { var value = pFloat[ySrcOffset]; ySrcOffset += height; value = (value - average) * (value - average); total += value; } totalSlices[y] = total; } } }); stdDev = totalSlices.AsParallel().Sum(); stdDev /= (float)(width * height); stdDev = (float)Math.Sqrt(stdDev); }
public static void CalculateAverageAndMaximumCPU(YDataFloat imageData, out float average, out float maximum) { int width = imageData.Width; int height = imageData.Height; // Calculate average and maximum average = 0.0f; maximum = 0.0f; var averageSlices = new float[height]; var maximumSlices = new float[height]; Parallel.For(0, height, (y) => { float avg = 0.0f; float max = 0.0f; for (int x = 0; x < width; x++) { var value = imageData.Data[x, y]; avg += value; if (max < value) { max = value; } } averageSlices[y] = avg; maximumSlices[y] = max; }); average = averageSlices.AsParallel().Sum(); average /= (float)(width * height); maximum = maximumSlices.AsParallel().Max(); }
public static YDataFloat NewData(int width, int height, float maximumValue, float defaultValue) { var result = new YDataFloat(new float[width, height], maximumValue); unsafe { fixed(float *pData = result.Data) { int dataLength = result.Width * result.Height; for (int i = 0; i < dataLength; i++) { pData[i] = defaultValue; } } } return(result); }
// -------------- Advance sliding window of averages -------------- public static void AdvanceEdgeDetectionAverage(ref YDataFloat edgeMapAverage, YDataFloat edgeDataNew, YDataFloat edgeDataOld, int edgeMapAverageCount) { var width = edgeMapAverage.Width; var height = edgeMapAverage.Height; float edgeMapAverageCountFloat = edgeMapAverageCount; unsafe { fixed(float *pAverage = edgeMapAverage.Data, pNew = edgeDataNew.Data, pOld = edgeDataOld.Data) { int size = width * height; for (int i = 0; i < size; i++) { pAverage[i] += (pNew[i] - pOld[i]) / edgeMapAverageCountFloat; } } } }
public static YDataFloat GenerateLogoDifferenceMap(YDataFloat edgeMapAvg, YDataFloat logoDetectionFrame, float detectionFrameAverage, float detectionFrameMaximum) { int width = edgeMapAvg.Width; int height = edgeMapAvg.Height; var maximum = edgeMapAvg.MaximumValue; var detectionFrameMaximumOffset = (detectionFrameMaximum - detectionFrameAverage); // Calculate absolute difference between values and apply power of important pixels from logoDetectionFrame var outputArray = new float[width, height]; Array.Clear(outputArray, 0, outputArray.Length); unsafe { fixed(float *pEdgeMapAvg = edgeMapAvg.Data, pLogoDetectionFrame = logoDetectionFrame.Data, pOutput = outputArray) { int size = width * height; for (int i = 0; i < size; i++) { var detectionFrameOffset = Math.Abs(pLogoDetectionFrame[i] - detectionFrameAverage); var edgeMapOffset = Math.Abs(pEdgeMapAvg[i] - detectionFrameAverage); if (edgeMapOffset < detectionFrameOffset) { var power = detectionFrameOffset / detectionFrameMaximumOffset; pOutput[i] = power * (detectionFrameOffset - edgeMapOffset) * 255.0f / detectionFrameMaximumOffset; } else { pOutput[i] = 0.0f; } //pOutput[i] = byte.MaxValue * power; } } } return(new YDataFloat(outputArray, maximum)); }
public static void AdvanceEdgeDetectionAverageAccel(AcceleratorTarget acceleratorTarget, ref YDataFloat edgeMapAverage, YDataFloat edgeDataNew, YDataFloat edgeDataOld, int edgeMapAverageCount) { var target = GetAcceleratorTarget(acceleratorTarget); var width = edgeMapAverage.Width; var height = edgeMapAverage.Height; float edgeMapAverageCountFloat = edgeMapAverageCount; var fpAverage = new FloatParallelArray(edgeMapAverage.Data); var fpNew = new FloatParallelArray(edgeDataNew.Data); var fpOld = new FloatParallelArray(edgeDataOld.Data); var fpAdjust = ParallelArrays.Subtract(fpNew, fpOld); fpAdjust = ParallelArrays.Divide(fpAdjust, edgeMapAverageCountFloat); var fpOutput = ParallelArrays.Subtract(fpAverage, fpAdjust); var output = target.ToArray2D(fpOutput); edgeMapAverage = new YDataFloat(output, edgeMapAverage.MaximumValue); }
public static YDataFloat GenerateEdgeDetectedImageAccel(AcceleratorTarget acceleratorTarget, YDataFloat imageData) { var target = GetAcceleratorTarget(acceleratorTarget); var width = imageData.Width; var height = imageData.Height; var fpInput = new FloatParallelArray(imageData.Data); var fpInputX = ParallelArrays.Shift(fpInput, new int[] { 1, 0 }); var fpInputY = ParallelArrays.Shift(fpInput, new int[] { 0, 1 }); var fpDX = ParallelArrays.Subtract(fpInputX, fpInput); var fpDY = ParallelArrays.Subtract(fpInputY, fpInput); var fpTotals = ParallelArrays.Add(fpDX, fpDY); var fpOutput = ParallelArrays.Divide(fpTotals, 2.0f); fpOutput = ParallelArrays.Add(fpOutput, imageData.MaximumValue / 2.0f); fpOutput = ParallelArrays.Max(fpOutput, 0.0f); fpOutput = ParallelArrays.Min(fpOutput, imageData.MaximumValue); var output = target.ToArray2D(fpOutput); return(new YDataFloat(output, imageData.MaximumValue)); }