public static void UpdateThresholds(ICollection <Tag> tags, Rectangle roiRect, uint frameBuffer, uint roiTexName) { // Setup resultTexName framebuffer int[] oldViewPort = new int[4]; GL.GetInteger(GetPName.Viewport, oldViewPort); GL.Viewport(0, 0, roiRect.Size.Width, roiRect.Size.Height); int fboOld = GLHelper.bindFrameBuffer(frameBuffer, roiTexName); float[] histR = new float[256]; float[] histG = new float[256]; float[] histB = new float[256]; // TODO: cache tag thresholds and only recalculate when dirty (otherwise many tags will impeede performance) if (tags.Count > 0) { // Rectangle localRoiRect = new Rectangle (0, 0, roiRect.Width, roiRect.Height); int sampleWidth = 100; int pixelCount = sampleWidth * sampleWidth; byte[] pixels = new byte[pixelCount * 4]; foreach (Tag tag in tags) { if (tag.calculateThreshold) { tag.calculateThreshold = false; Rectangle sampleRect = tag.ThresholdSampleRect; Point loc = sampleRect.Location; loc.Offset(-roiRect.Location.X, -roiRect.Location.Y); sampleRect.Location = loc; // sampleRect = Rectangle.Intersect(tagRect, localRoiRect); // Skip rects outside roi if (sampleRect.Width == 0 || sampleRect.Height == 0) { continue; } // Clear histograms for (int i = 0; i < 256; i++) { histR [i] = 0; histG [i] = 0; histB [i] = 0; } // Read pixels GL.ReadPixels(sampleRect.Left, sampleRect.Top, sampleRect.Width, sampleRect.Height, PixelFormat.Rgba, PixelType.UnsignedByte, pixels); // Get color of tag (center of sample) int pxIdx = pixelCount * 2 + sampleRect.Width * 2; tag.Color [0] = pixels [pxIdx] & 0xff; tag.Color [1] = pixels [pxIdx + 1] & 0xff; tag.Color [2] = pixels [pxIdx + 2] & 0xff; // Get histogram for pixels around tag int count = pixelCount * 4; int j = 0; while (j < count) { int iR = pixels [j++] & 0xff; int iG = pixels [j++] & 0xff; int iB = pixels [j++] & 0xff; int iA = pixels [j++] & 0xff; if (iA > 0) { histR [iR]++; histG [iG]++; histB [iB]++; } } // Fill gaps in threshold to prepare it for threshold finding Histogram.FillGaps(histR); Histogram.FillGaps(histG); Histogram.FillGaps(histB); // Find threshold tag.Threshold [0] = OtsuThreshold.getThreshold(histR); tag.Threshold [1] = OtsuThreshold.getThreshold(histG); tag.Threshold [2] = OtsuThreshold.getThreshold(histB); } } } // unbind framebuffer and cleanup viewport GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld); GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]); }
public static void GetROIThreshold(Rectangle rect, uint[] pixelBuffer, int[] min, int[] max, uint frameBuffer, uint roiTexName) { // Setup viewport int[] oldViewPort = new int[4]; GL.GetInteger(GetPName.Viewport, oldViewPort); GL.Viewport(0, 0, rect.Size.Width, rect.Size.Height); int fboOld = GLHelper.bindFrameBuffer(frameBuffer, roiTexName); // Update ROI histogram // TODO: use already allocated segmentation buffer { float[] histR = new float[256]; float[] histG = new float[256]; float[] histB = new float[256]; int pixelCount = rect.Width * rect.Height; byte[] pixels = new byte[pixelCount * 4]; GL.ReadPixels(0, 0, rect.Width, rect.Height, PixelFormat.Rgba, PixelType.UnsignedByte, pixels); int count = pixelCount * 4; int j = 0; int sumR = 0, sumG = 0, sumB = 0; int sampleCount = 0; while (j < count) { int iR = pixels [j++] & 0xff; int iG = pixels [j++] & 0xff; int iB = pixels [j++] & 0xff; int iA = pixels [j++] & 0xff; if (iA > 0) { sampleCount++; sumR += iR; sumG += iG; sumB += iB; histR [iR]++; histG [iG]++; histB [iB]++; } } float avrR = (float)sumR / (float)sampleCount; // float avrG = (float)sumG/(float)sampleCount; // float avrB = (float)sumB/(float)sampleCount; Histogram.FillGaps(histR); Histogram.FillGaps(histG); Histogram.FillGaps(histB); // Find threshold int thresholdR = OtsuThreshold.getThreshold(histR); int thresholdG = OtsuThreshold.getThreshold(histG); int thresholdB = OtsuThreshold.getThreshold(histB); if (avrR > thresholdR) { min[0] = 0; min[1] = 0; min[2] = 0; max[0] = thresholdR; max[1] = thresholdG; max[2] = thresholdB; } else { min[0] = thresholdR; min[1] = thresholdG; min[2] = thresholdB; max[0] = 1; max[1] = 1; max[2] = 1; } } // unbind framebuffer GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld); GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]); }