/// <summary> /// Stop calibrating, saving the current brightness correction parameters /// </summary> public void StopCalibration() { calibrating = false; float[] temp = new float[correctionFactor.Length]; correctionFactor.Gather(temp); FileStream stream = new FileStream("correctionFactor.dat", FileMode.OpenOrCreate); foreach (float value in temp) { stream.Write(BitConverter.GetBytes(value), 0, 4); } stream.Close(); }
/// <summary> /// Called every time a new frame shows up from the camera /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void provider_ImageTransaction(object sender, ImageReceivedEventArgs e) { if (stopping || e == null || e.PixelData == null) { return; } if (Monitor.TryEnter(this)) { imgGPU.Scatter(e.PixelData); if (calibrating) { // compute a running mean of each pixel worker.Launch(RunningMean_Kernel, lp, e.Width, imgGPU.Ptr, meanImg.Ptr, numCalibrationSamples); numCalibrationSamples++; // compute the mean over the full mean image, using a reduction operation addReduce.Reduce(meanImg.Ptr, scalarOutput.Ptr, numPixels); var mean = scalarOutput.GatherScalar(); mean /= numPixels; // update the correction factor for each pixel worker.Launch(UpdateCorrectionFactor_Kernel, lp, e.Width, meanImg.Ptr, correctionFactor.Ptr, mean); } if (correctBrightness) { worker.Launch(ApplyCorrectionFactor_Kernel, lp, e.Width, correctionFactor.Ptr, imgGPU.Ptr); imgGPU.Gather(e.PixelData); } img.Bytes = e.PixelData; // note: have to do this last, because if you set it earlier but then modify the bytes it won't update the image // trigger a new frame event OnFrameAvailable(new VideoFrame { Image = img, ImageGPU = imgGPU, Timestamp = e.TimeStamp }); Monitor.Exit(this); } }
/// <summary> /// Computes an LBP histogram over the full image /// </summary> /// <param name="image">an EMGU image</param> /// <returns>a normalized histogram of uniform LBP patterns</returns> public float[] GetHistogram(VideoFrame frame) { // reshape the image data to a 1D array, and push it to the GPU //Buffer.BlockCopy(image.Data, 0, imageData, 0, image.Width * image.Height); //byte[, ,] data = image.Data; //int w = image.Width, h = image.Height; //for (int i = 0; i < h; i++) // for (int j = 0; j < w; j++) // imageData[i * w + j] = data[i, j, 0]; //imageGPU.ScatterScalar(data[i, j, 0], i * w + j); //imageGPU.Scatter(image); // run the LBP kernel worker.Launch(LBP_Kernel, lp, frame.Width, frame.Height, frame.ImageGPU.Ptr, lbpImageGPU.Ptr, varImageGPU.Ptr, binLookupGPU.Ptr, neighborCoordinateXGPU.Ptr, neighborCoordinateYGPU.Ptr, varBinsGPU.Ptr); // zero out the histogram data on the GPU, then compute a new histogram from the LBP patterns for (int i = 0; i < hist.Length; i++) { hist[i] = 0; } histGPU.Scatter(hist); worker.Launch(Hist_Kernel, lp, frame.Width, frame.Height, lbpImageGPU.Ptr, varImageGPU.Ptr, histGPU.Ptr); histGPU.Gather(useSubuniform ? hist2 : hist); if (useSubuniform) { // shift the histogram segments to achieve rotation invariance hist[0] = hist2[0]; hist[1] = hist2[1]; for (int m = 0; m < numNeighbors - 1; m++) { int maxIndex = 0; int max = 0; for (int w = 0; w < numNeighbors; w++) { int v = 0; for (int i = 0; i < numVarBins; i++) { v += hist2[(m * numNeighbors + w) * numVarBins + i]; } if (v > max) { max = v; maxIndex = w; } } for (int w = 0; w < numNeighbors; w++) { for (int i = 0; i < numVarBins; i++) { hist[(m * numNeighbors + w) * numVarBins + i] = hist2[(m * numNeighbors + (w + maxIndex) % numNeighbors) * numVarBins + i]; } } } } // normalize the histogram (doesn't need to run on GPU) int n = (frame.Width - 2 * radius) * (frame.Height - 2 * radius); float[] histNorm = new float[hist.Length]; //for (int i = 0; i < hist.Length; i++) histNorm[i] = (float)hist[i] / n; for (int i = 0; i < hist.Length; i++) { histNorm[i] = hist[i]; } return(histNorm); }
/// <summary> /// Computes an LBP histogram over the full image /// </summary> /// <param name="image">an EMGU image</param> /// <returns>a normalized histogram of uniform LBP patterns</returns> public float[] GetHistogram(VideoFrame frame) { // build the scale space and select the best scale for each pixel worker.Launch(ConvertFloat_Kernel, lp, frame.Width, frame.Height, frame.ImageGPU.Ptr, floatImageGPU.Ptr); for (int i = 0; i < numScales; i++) { worker.Launch(Filter_Symmetric_Kernel, lp, frame.Width, frame.Height, floatImageGPU.Ptr, scaledImages[i].Ptr, filtersGPU[i].Ptr, filterSizes[i]); } worker.Launch(EstimateScale_Kernel, lp, frame.Width, frame.Height, 1.0f, scaledImagePointers.Ptr, pixelScaleImage.Ptr); // run the LBP kernel worker.Launch(LBP_Kernel, lp, frame.Width, frame.Height, frame.ImageGPU.Ptr, lbpImageGPU.Ptr, varImageGPU.Ptr, subuniformBinsGPU.Ptr, neighborCoordinateXGPU.Ptr, neighborCoordinateYGPU.Ptr, pixelScaleImage.Ptr, varBinsGPU.Ptr); // zero out the histogram data on the GPU, then compute a new histogram from the LBP patterns for (int i = 0; i < hist.Length; i++) { hist[i] = 0; } histGPU.Scatter(hist); worker.Launch(Hist_Kernel, lp, frame.Width, frame.Height, lbpImageGPU.Ptr, varImageGPU.Ptr, histGPU.Ptr); histGPU.Gather(hist2); // shift the histogram segments to achieve rotation invariance hist[0] = hist2[0]; hist[1] = hist2[1]; for (int m = 0; m < numNeighbors - 1; m++) { int maxIndex = 0; int max = 0; for (int w = 0; w < numNeighbors; w++) { int v = 0; for (int i = 0; i < numVarBins; i++) { v += hist2[(m * numNeighbors + w) * numVarBins + i]; } if (v > max) { max = v; maxIndex = w; } } for (int w = 0; w < numNeighbors; w++) { for (int i = 0; i < numVarBins; i++) { hist[(m * numNeighbors + w) * numVarBins + i] = hist2[(m * numNeighbors + (w + maxIndex) % numNeighbors) * numVarBins + i]; } } } // normalize the histogram (doesn't need to run on GPU) int n = (frame.Width) * (frame.Height); float[] histNorm = new float[hist.Length]; for (int i = 0; i < hist.Length; i++) { histNorm[i] = (float)hist[i] / n; } return(histNorm); }