Пример #1
0
        public static void updateROIImage(Rectangle roiRect, uint frameBuffer, uint imageTexName, Size imageSize, uint roiTexName, uint roiMaskTexName)
        {
            GLHelper.GetError();

            // Setup viewport
            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);

            // Render to source texture
            float left   = (float)roiRect.Location.X / (float)imageSize.Width;
            float right  = (float)(roiRect.Location.X + roiRect.Size.Width) / (float)imageSize.Width;
            float top    = (float)roiRect.Location.Y / (float)imageSize.Height;
            float button = (float)(roiRect.Location.Y + roiRect.Size.Height) / (float)imageSize.Height;

            // NB: texture coords are mirrored vertically
            float[] texCoords = { right, top,  right, button, left,
                                  top,   left, button };

            // Render source
            Matrix4   mat = Matrix4.CreateOrthographicOffCenter(0, (float)roiRect.Size.Width, 0, (float)roiRect.Size.Height, -1.0f, 1.0f);
            Rectangle r   = new Rectangle(0, 0, roiRect.Width, roiRect.Height);

            GLHelper.DrawSprite(imageTexName, r, mat, texCoords, Vector4.One);

            // Render mask onto source
            GL.Enable(EnableCap.Blend);

            GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.OneMinusSrcAlpha);
            GLHelper.DrawSprite(roiMaskTexName, r, mat);

            GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero);

            GL.Disable(EnableCap.Blend);

            // unbind framebuffer
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld);
            GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]);

            GLHelper.GetError();
        }
Пример #2
0
        public static void updateROIMask(Rectangle roiRect, Size imageSize, uint frameBuffer, uint roiMaskTexName, uint maskTexName)
        {
            GLHelper.GetError();

            // Setup viewport
            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, roiMaskTexName);

            // Fill with 1.1.1.1
            GL.ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
            GL.Clear(ClearBufferMask.ColorBufferBit);

            GLHelper.GetError();

            // Draw crop
            if (true)
            {
                float[] vertices = GLHelper.CreateSphereVertices(new Vector2((float)roiRect.Size.Width * 0.5f, (float)roiRect.Size.Height * 0.5f), (float)roiRect.Size.Height * 0.5f, true);

                // Set Model view
                Matrix4 MVPMatrix = Matrix4.CreateOrthographicOffCenter(0, (float)roiRect.Size.Width, 0, (float)roiRect.Size.Height, -1.0f, 1.0f);

                AmbientShader shader = AmbientShader.Singleton;
                shader.Use();
                shader.SetColor(new Vector4(0, 0, 0, 0));
                shader.SetMVPMatrix(MVPMatrix);
                shader.EnableVertices(2, VertexAttribPointerType.Float, false, 0, vertices);

                GLHelper.GetError();

                GL.DrawArrays(BeginMode.TriangleFan, 0, vertices.Length / 2);

                shader.DisableVertices();
            }

            // Draw mask
            if (true)
            {
                // Render to source texture
                float left   = (float)roiRect.Location.X / (float)imageSize.Width;
                float right  = (float)(roiRect.Location.X + roiRect.Size.Width) / (float)imageSize.Width;
                float top    = (float)roiRect.Location.Y / (float)imageSize.Height;
                float button = (float)(roiRect.Location.Y + roiRect.Size.Height) / (float)imageSize.Height;

                // NB: texture coords are mirrored vertically
                float[] texCoords = { right, top,  right, button, left,
                                      top,   left, button };

                Matrix4   mat = Matrix4.CreateOrthographicOffCenter(0, (float)roiRect.Size.Width, 0, (float)roiRect.Size.Height, -1.0f, 1.0f);
                Rectangle r   = new Rectangle(0, 0, roiRect.Width, roiRect.Height);

                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                GLHelper.DrawSprite(maskTexName, r, mat, texCoords, Vector4.One);

                GL.Disable(EnableCap.Blend);
            }



            // unbind framebuffer
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld);

            // Cleanup viewport
            GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]);

            GLHelper.GetError();
        }
Пример #3
0
        static public void UpdateSegmentation(ICollection <Tag> tags, Rectangle roiRect, uint frameBuffer,
                                              uint thresholdTexName, uint roiTexName, uint[] segmentationPixelData,
                                              int[] roiThresholdMin, int[] roiThresholdMax)
        {
            float[] thresholdMin = { 1, 1, 1 };
            float[] thresholdMax = { 0, 0, 0 };

            if (tags.Count == 0)
            {
                thresholdMin = new float[] { (float)roiThresholdMin[0] / 255.0f, (float)roiThresholdMin[1] / 255.0f, (float)roiThresholdMin[2] / 255.0f };
                thresholdMax = new float[] { (float)roiThresholdMax[0] / 255.0f, (float)roiThresholdMax[1] / 255.0f, (float)roiThresholdMax[2] / 255.0f };
            }
            else
            {
                // TODO: use ALL thresholds
                foreach (Tag tag in tags)
                {
                    float[] min = new float[3];
                    float[] max = new float[3];
                    tag.GetNormalizedMaxMin(ref min, ref max);

                    thresholdMin[0] = Math.Min(thresholdMin[0], min[0]);
                    thresholdMin[1] = Math.Min(thresholdMin[1], min[1]);
                    thresholdMin[2] = Math.Min(thresholdMin[2], min[2]);
                    thresholdMax[0] = Math.Max(thresholdMax[0], max[0]);
                    thresholdMax[1] = Math.Max(thresholdMax[1], max[1]);
                    thresholdMax[2] = Math.Max(thresholdMax[2], max[2]);
//					thresholdMin = new float[3] { min[0], min[1], min[2]};
//					thresholdMax = new float[3] { max[0], max[1], max[2]};

                    Console.WriteLine("color:" + tag.Color[0] + "," + tag.Color[1] + "," + tag.Color[2]);
                }
            }

            // Setup thresholdTexName as 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, thresholdTexName);

            // Clear
            GL.ClearColor(1.0f, 0.0f, 0.0f, 1.0f);
            GL.Clear(ClearBufferMask.ColorBufferBit);


            float x      = 0;
            float y      = 0;
            float width  = roiRect.Size.Width;
            float height = roiRect.Size.Height;

            float[] Vertices =
            {
                x + width, y,
                x + width, y + height,
                x,         y,
                x,         y + height
            };

            float[] Texture = { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };

            Vector4 color = new Vector4(1, 1, 1, 1);

            Matrix4 mat = Matrix4.CreateOrthographicOffCenter(0, (float)roiRect.Size.Width, 0, (float)roiRect.Size.Height, -1.0f, 1.0f);

            ThresholdShader shader = ThresholdShader.Singleton;

            // Use shader
            shader.Use();

            // Set texture
            shader.SetTexture(roiTexName);

            // Set threshold
            Vector4 vMin = new Vector4(thresholdMin[0], thresholdMin[2], thresholdMin[2], 1);
            Vector4 vMax = new Vector4(thresholdMax[0], thresholdMax[2], thresholdMax[2], 1);

            shader.SetThreshold(vMin, vMax);
            shader.setColor(color);

            // Set Model view
            GL.UniformMatrix4(shader.muMVPMatrixHandle, 1, false, ref mat.Row0.X);

            // Set vertex and texture coords
            GL.EnableVertexAttribArray(shader.maPositionHandle);
            GL.EnableVertexAttribArray(shader.maTexCoordHandle);

            GL.VertexAttribPointer(shader.maPositionHandle, 2, VertexAttribPointerType.Float, false, 0, Vertices);
            GL.VertexAttribPointer(shader.maTexCoordHandle, 2, VertexAttribPointerType.Float, false, 0, Texture);

            GL.DrawArrays(BeginMode.TriangleStrip, 0, 4);

            GL.DisableVertexAttribArray(shader.maPositionHandle);
            GL.DisableVertexAttribArray(shader.maTexCoordHandle);

            // Read pixel data
            {
                GL.ReadPixels(0, 0, roiRect.Size.Width, roiRect.Size.Height, PixelFormat.Rgba, PixelType.UnsignedByte, segmentationPixelData);
//				GL.ReadPixels<uint>(0, 0, roiRect.Size.Width, roiRect.Size.Height, All.Rgba, All.UnsignedByte, segmentationPixelData);
            }

            // unbind framebuffer and cleanup viewport
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld);
            GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]);
        }
Пример #4
0
        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]);
        }
Пример #5
0
        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]);
        }
Пример #6
0
        public static void MaskDraw(Vector2 pos, Vector2 prevPos, bool bForeground, uint frameBuffer,
                                    uint texName, Size texSize, float[] sphereVertices, int scale)
        {
            // FIXME: radius is in image space and needs to be dps adjusted

            // Setup viewport
            int[] oldViewPort = new int[4];
            GL.GetInteger(GetPName.Viewport, oldViewPort);
            GL.Viewport(0, 0, texSize.Width, texSize.Height);
            int fboOld = GLHelper.bindFrameBuffer(frameBuffer, texName);

            Vector4 foreground = new Vector4(1, 1, 1, 1);
            Vector4 background = new Vector4(0, 0, 0, 0);
            Vector4 color      = bForeground ? foreground : background;

            AmbientShader shader = AmbientShader.Singleton;

            shader.Use();
            shader.SetColor(color);

            Matrix4 ProjMatrix = Matrix4.CreateOrthographicOffCenter(0, (float)texSize.Width, 0, (float)texSize.Height, -1.0f, 1.0f);

            // Draw sphere at pos
            {
                // Set Model view
                Matrix4 MVPMatrix = Matrix4.Scale(scale) * Matrix4.CreateTranslation(new Vector3(pos)) * ProjMatrix;

                shader.SetMVPMatrix(MVPMatrix);
                shader.EnableVertices(2, VertexAttribPointerType.Float, false, 0, sphereVertices);

                GLHelper.GetError();

                GL.DrawArrays(BeginMode.TriangleFan, 0, sphereVertices.Length / 2);

                shader.DisableVertices();
            }

            // Connect prev to current
            if (!pos.Equals(prevPos))
            {
                shader.SetMVPMatrix(ProjMatrix);


                //				shader.SetMVPMatrix(projMatrix);

                //				Vector2 v0 = CCContext.ViewToModel(prevPos, modelViewMatrix);
                //				Vector2 v1 = CCContext.ViewToModel(pos, modelViewMatrix);
                Vector2 v0 = prevPos;
                Vector2 v1 = pos;

                Vector3 up  = new Vector3(0, 0, 1);
                Vector3 dir = new Vector3(v1) - new Vector3(v0);
                dir = Vector3.Normalize(dir);

                Vector3 cross = Vector3.Cross(up, dir) * scale;

                float[] vertices = new float[4 * 2];
                int     i        = 0;

                vertices[i++] = v0.X - cross.X;
                vertices[i++] = v0.Y - cross.Y;

                vertices[i++] = v0.X + cross.X;
                vertices[i++] = v0.Y + cross.Y;

                vertices[i++] = v1.X - cross.X;
                vertices[i++] = v1.Y - cross.Y;

                vertices[i++] = v1.X + cross.X;
                vertices[i++] = v1.Y + cross.Y;

                shader.EnableVertices(2, VertexAttribPointerType.Float, false, 0, vertices);

                GL.DrawArrays(BeginMode.TriangleStrip, 0, 4);

                //				GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, 4);

                shader.DisableVertices();
            }

            // unbind framebuffer
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld);
            GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]);
        }
Пример #7
0
        private void CreateSaveImage(ICollection <Tag> tagArray)
        {
            if (SaveCountResult == null)
            {
                return;
            }

            Size size          = ccContext.ImageSize;
            uint outputTexName = 0;

            // Generate texture
            GL.GenTextures(1, out outputTexName);
            CCContext.setupTexture(outputTexName, size, IntPtr.Zero);

            // Setup viewport
            int[] oldViewPort = new int[4];
            GL.GetInteger(GetPName.Viewport, oldViewPort);
            GL.Viewport(0, 0, size.Width, size.Height);
            int fboOld = GLHelper.bindFrameBuffer(frameBuffer, outputTexName);

            GL.Disable(EnableCap.Blend);

            Matrix4 projectionMatrix = Matrix4.CreateOrthographicOffCenter(0, (float)size.Width, 0, (float)size.Height, -1.0f, 1.0f);
//			Matrix4 projectionMatrix = ccContext.ProjectionMatrix;
            Matrix4 modelViewMatrix = Matrix4.Identity;

            // Draw image
            {
                Matrix4   mat       = modelViewMatrix * projectionMatrix;
                Rectangle imageRect = new Rectangle(0, 0, (int)size.Width, (int)size.Height);
                GLHelper.DrawSprite(ccContext.ImageTexName, imageRect, mat);
            }

            // Draw ROI
            Vector4    outlineColor = ColorHelper.ColorToVec(ColorHelper.ROIEdge);
            Vector4    bgColor      = ColorHelper.ColorToVec(ColorHelper.ROIBackground);
            float      outlineWidth = 1.0f;
            RectangleF rect         = new RectangleF(PointF.Empty, new SizeF(size));

            CountLayerHelper.DrawROI(rect, roiSphere.center, roiSphere.radius, roiRect, roiMaskTexName, outlineColor, outlineWidth, bgColor, modelViewMatrix, projectionMatrix);

            // Regions
            CountLayerHelper.DrawRegions(regions, modelViewMatrix, projectionMatrix);

            // Draw tags
            {
                float tagSize = 16;
                CountLayerHelper.drawTags(tagArray, null, true, modelViewMatrix, projectionMatrix, tagSize);
            }

            // allocate array and read pixels into it.
            int myDataLength = size.Width * size.Height * 4;

            byte[] buffer = new byte[myDataLength];
            GL.ReadPixels(0, 0, size.Width, size.Height, PixelFormat.Rgba, PixelType.UnsignedByte, buffer);

            // Call save image event
            SaveCountResult(buffer, size, tags.Count, regions.Count);

            buffer = null;

            GL.DeleteTextures(1, ref outputTexName);

            // unbind framebuffer
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld);
            GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]);
        }