/// <summary> /// Private Constructor /// </summary> Camera() { try { // pre-allocate and initialize the variables and data structures for brightness correction imgGPU = worker.Malloc <byte>(new byte[640 * 640]); meanImg = worker.Malloc <float>(new float[640 * 640]); addReduce = DeviceSumModuleF32.Default.Create(numPixels); correctionFactor = worker.Malloc <float>(640 * 640); float[] temp = new float[640 * 640]; for (int i = 0; i < temp.Length; i++) { temp[i] = 1; } correctionFactor.Scatter(temp); scalarOutput = worker.Malloc <float>(1); if (File.Exists("correctionFactor.dat")) { FileStream stream = new FileStream("correctionFactor.dat", FileMode.Open); byte[] buffer = new byte[640 * 640 * 4]; stream.Read(buffer, 0, (int)Math.Min(buffer.Length, stream.Length)); for (int i = 0; i < 640 * 640; i++) { temp[i] = BitConverter.ToSingle(buffer, 4 * i); } stream.Close(); correctionFactor.Scatter(temp); } // initialize CUDA parameters var blockDims = new dim3(32, 32); var gridDims = new dim3(Common.divup(640, blockDims.x), Common.divup(640, blockDims.y)); lp = new LaunchParam(gridDims, blockDims); // set up the camera parameters and events provider = new IduleProviderCsCam(0); provider.Initialize(); if (provider.IsConnected) { provider.ImageTransaction += provider_ImageTransaction; provider.Interrupt += provider_Interrupt; provider.Exception += camera_Exception; provider.WriteRegister(new NanEyeGSRegisterPayload(false, 0x05, true, 0, prescaler)); provider.WriteRegister(new NanEyeGSRegisterPayload(false, 0x06, true, 0, exposure)); ProcessingWrapper.pr[0].ReduceProcessing = true; } } catch (Exception ex) { OnError(ex.Message); } }
/// <summary> /// Reset the brightness correction parameters and start calibrating them /// </summary> public void StartCalibration() { calibrating = true; meanImg.Scatter(new float[640 * 640]); float[] temp = new float[640 * 640]; for (int i = 0; i < temp.Length; i++) { temp[i] = 1; } correctionFactor.Scatter(temp); numCalibrationSamples = 0; }
/// <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); }