Esempio n. 1
0
        // Returns a map of focus ranks, defined as follows:
        //  for each pixel C of input image (but borders)
        //      for each pixel N of center's neighborhood
        //          accumulate |C-P| * W where W is a weight depending on distance between C and N
        public FloatMap GetContrastMap(FloatMap imgfIn)
        {
            const float k1 = 0.104167f;
            const float k2 = 0.145833f;

            int h      = imgfIn.H;
            int w      = imgfIn.W;
            int stride = imgfIn.Stride;

            var contrImgfs = new FloatMap(w, h);

            int lineStart = stride;

            for (int y = 1; y < h - 1; ++y)
            {
                var i = lineStart + 1;
                for (int x = 1; x < w - 2; ++x) // -2 ?????
                {
                    var c = imgfIn[i];

                    // TODO: Optimize with scanlines
                    contrImgfs[i] = (Math.Abs(c - imgfIn[i + stride]) + Math.Abs(c - imgfIn[i - stride]) + Math.Abs(c - imgfIn[i + 1]) + Math.Abs(c - imgfIn[i - 1])) * k2 +
                                    (Math.Abs(c - imgfIn[i + stride + 1]) + Math.Abs(c - imgfIn[i + stride - 1]) + Math.Abs(c - imgfIn[i - stride + 1]) + Math.Abs(c - imgfIn[i - stride - 1])) * k1;
                    i += 1;
                }
                lineStart += stride;
            }
            return(contrImgfs);
        }
Esempio n. 2
0
        // Blurs image; this has been written quickly and without reference;
        // should be modified in order to use a true gaussian kernel;
        // is left as is because shortly all convolution-like functions
        // will be handled by a single method (possibly with OpenCL)
        public FloatMap QuickBlurMap(FloatMap imgfIn)
        {
            int h      = imgfIn.H;
            int w      = imgfIn.W;
            int stride = imgfIn.Stride;

            var imgfOut = new FloatMap(w, h);

            const float k1 = 0.1715728f; // w = 2
            const float k2 = 0.0857864f; // w = 1
            const float k3 = 0.0606601f; // w = 1/1.4 = 0.7

            int lineStart = stride;

            for (int y = 1; y < h - 1; ++y)
            {
                int i = lineStart + 1;;
                for (int x = 1; x < w - 1; ++x)
                {
                    imgfOut[i] = (imgfIn[i]) * k1 +
                                 (imgfIn[i + stride] + imgfIn[i - stride] + imgfIn[i + 1] + imgfIn[i - 1]) * k2 +
                                 (imgfIn[i + stride + 1] + imgfIn[i + stride - 1] + imgfIn[i - stride + 1] + imgfIn[i - stride - 1]) * k3;
                    ++i;
                }
                lineStart += stride;
            }
            return(imgfOut);
        }
Esempio n. 3
0
        // Returns an image which sizes are each half the original value;
        // will be probably replaced with reduction/expansion-style OpenCl operation
        public FloatMap HalfMap(FloatMap imgfIn)
        {
            int h      = imgfIn.H;
            int w      = imgfIn.W;
            int stride = imgfIn.Stride;

            int hh = h >> 1;
            int hw = w >> 1;

            var imgfOut = new FloatMap(hw, hh);

            int hStride = imgfOut.Stride;

            int lineStart  = 0;
            int hLineStart = 0;

            for (int y = 0; y < hh; ++y)
            {
                int i  = lineStart;
                int hi = hLineStart;
                for (int x = 0; x < hw; ++x)
                {
                    imgfOut[hi] = (imgfIn[i] + imgfIn[i + stride] + imgfIn[i + 1] + imgfIn[i + stride + 1]) * 0.25f;
                    i          += 2;
                    ++hi;
                }
                lineStart  += stride << 1;
                hLineStart += hStride;
            }
            return(imgfOut);
        }
Esempio n. 4
0
        // returns an image which sizes are each double the original value;
        // will be probably replaced with reduction/expansion-style
        // OpenCl operation
        public FloatMap DoubleMap(FloatMap imgfIn)
        {
            int h = imgfIn.H;
            int w = imgfIn.W;

            int dh = h * 2;
            int dw = w * 2;

            var imgfOut   = new FloatMap(dw, dh);
            int dstStride = imgfOut.Stride;

            float dx = 0, dy = 0;

            int dLineStart = 0;

            for (int y = 0; y < dh - 2; ++y)
            {
                dx = 0;
                int i = dLineStart;
                for (int x = 0; x < dw - 2; ++x)
                {
                    imgfOut[i] = imgfIn[dx, dy];
                    dx        += 0.5f;
                    ++i;
                }
                dy         += 0.5f;
                dLineStart += dstStride;
            }
            return(imgfOut);
        }
Esempio n. 5
0
        public static FloatMap GaussianBlur(FloatMap imgfIn, float sigma)
        {
            FloatMap blurMask = createBlurMask(sigma);
            bool     dummy;

            return(convolute(imgfIn, blurMask, out dummy));
        }
Esempio n. 6
0
        // http://www.thebigblob.com/gaussian-blur-using-opencl-and-the-built-in-images-textures/
        // http://haishibai.blogspot.it/2009/09/image-processing-c-tutorial-4-gaussian.html
        FloatMap createBlurMask(float sigma)
        {
            int      maskSize         = (int)Math.Ceiling(3.0f * sigma);
            int      _2maskSizePlus1  = (maskSize << 1) + 1; // stupid C# compiler gives precedence to sum
            FloatMap mask             = new FloatMap(_2maskSizePlus1, _2maskSizePlus1);
            float    sum              = 0.0f;
            float    temp             = 0.0f;
            float    _2sigmaSqrInvNeg = -1 / (sigma * sigma * 2);

            for (int a = -maskSize; a <= maskSize; ++a)
            {
                for (int b = -maskSize; b <= maskSize; ++b)
                {
                    temp = (float)Math.Exp(((float)(a * a + b * b) * _2sigmaSqrInvNeg));
                    sum += temp;
                    mask[a + maskSize + (b + maskSize) * _2maskSizePlus1] = temp;
                }
            }

            // Normalize the mask
            int _2maskSizePlus1Sqr = _2maskSizePlus1 * _2maskSizePlus1;

            for (int i = 0; i < _2maskSizePlus1Sqr; ++i)
            {
                mask[i] = mask[i] / sum;
            }

            return(mask);
        }
Esempio n. 7
0
        // Resizes map to arbitrary size (but it's better suited to upscale)
        public FloatMap ResizeMap(FloatMap imgfIn, int dstW, int dstH)
        {
            int srcH = imgfIn.H;
            int srcW = imgfIn.W;

            float xk = (float)srcW / (float)dstW;
            float yk = (float)srcH / (float)dstH;

            FloatMap imgOut = new FloatMap(dstW, dstH);

            int stride = imgOut.Stride;

            float dy        = 0;
            int   lineStart = 0;

            for (int y = 0; y < dstH; ++y)
            {
                float dx = 0;
                int   i  = lineStart;
                for (int x = 0; x < dstW; ++x)
                {
                    imgOut[i] = imgfIn[dx, dy];
                    dx       += xk;
                    ++i;
                }
                lineStart += stride;
                dy        += yk;
            }

            return(imgOut);
        }
Esempio n. 8
0
        // images cannot be read_write... so let's continue using plain buffers
        // should implement this in a way that allows imgfAccu to be loaded only once
        // should test for image size consistency
        public void Accumulate(FloatMap imgfAccu, FloatMap imgfSrc, float k)
        {
            var kernel = _kernels["accumulate"];

            // Creation of on-device memory objects
            IMem <float> accuMapBuffer = Cl.CreateBuffer <float>(_context, MemFlags.ReadWrite, imgfAccu.Size, out err); // why MemFlags.CopyHostPtr doesn't work here (and forces me to manual copy) ???

            assert(err, "accu buf creation");

            IMem <float> srcMapBuffer = Cl.CreateBuffer <float>(_context, MemFlags.WriteOnly, imgfSrc.Size, out err);

            assert(err, "src buf creation");

            // Set memory objects as parameters to kernel
            err = Cl.SetKernelArg(kernel, 0, intPtrSize, accuMapBuffer);
            assert(err, "accu map setKernelArg");

            err = Cl.SetKernelArg(kernel, 1, intPtrSize, srcMapBuffer);
            assert(err, "src map setKernelArg");

            err = Cl.SetKernelArg(kernel, 2, intSize, imgfAccu.Stride);
            assert(err, "in stride setKernelArg");

            err = Cl.SetKernelArg(kernel, 3, intSize, imgfSrc.Stride);
            assert(err, "out stride setKernelArg");

            err = Cl.SetKernelArg(kernel, 4, floatSize, k);
            assert(err, "out stride setKernelArg");

            // write actual data into memory object
            Event clevent;

            err = Cl.EnqueueWriteBuffer <float>(_commandsQueue, accuMapBuffer, Bool.True, 0, imgfAccu.Size, imgfAccu._buf, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "write accu buffer");

            err = Cl.EnqueueWriteBuffer <float>(_commandsQueue, srcMapBuffer, Bool.True, 0, imgfSrc.Size, imgfSrc._buf, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "write src buffer");

            // execute
            err = Cl.EnqueueNDRangeKernel(_commandsQueue, kernel, 2,
                                          new[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 },                           // offset
                                          new[] { new IntPtr(imgfAccu.W), new IntPtr(imgfAccu.H), (IntPtr)1 }, // range
                                          null, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "Cl.EnqueueNDRangeKernel");

            // sync
            Cl.Finish(_commandsQueue);

            // read from output memory object into actual buffer
            err = Cl.EnqueueReadBuffer <float>(_commandsQueue, accuMapBuffer, Bool.True, imgfAccu._buf, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "read output buffer");

            Cl.ReleaseMemObject(srcMapBuffer);
            Cl.ReleaseMemObject(accuMapBuffer); // maybe i could return this without disposing; would affect non-OpenCl implementation
        }
Esempio n. 9
0
 // Returns an image which sizes are each 2^times the original value;
 // will be probably replaced with reduction/expansion-style
 // OpenCl operation
 public FloatMap DoubleMap(FloatMap imgfIn, int times)
 {
     for (int i = 0; i < times; ++i)
     {
         imgfIn = DoubleMap(imgfIn);
     }
     return(imgfIn);
 }
Esempio n. 10
0
 // Returns an image which sizes are each 1/2^times the original value;
 // will be probably replaced with reduction/expansion-style OpenCl operation
 public static FloatMap HalfMap(FloatMap imgfIn, int times)
 {
     for (int i = 0; i < times; ++i)
     {
         imgfIn = HalfMap(imgfIn);
     }
     return(imgfIn);
 }
Esempio n. 11
0
        // not so tailored for SIMT...
        public void Accumulate(FloatMap imgfAccu, FloatMap imgfSrc, float k)
        {
            var kernel = _kernels["accumulate"];

            // Creation of on-device memory objects
            IMem<float> accuMapBuffer = Cl.CreateBuffer<float>(_context, MemFlags.ReadWrite, imgfAccu.Size, out err);
            assert(err, "accu buf creation");

            IMem<float> srcMapBuffer = Cl.CreateBuffer<float>(_context, MemFlags.WriteOnly, imgfSrc.Size, out err);
            assert(err, "src buf creation");

            // Set memory objects as parameters to kernel
            err = Cl.SetKernelArg(kernel, 0, intPtrSize, accuMapBuffer);
            assert(err, "accu map setKernelArg");

            err = Cl.SetKernelArg(kernel, 1, intPtrSize, srcMapBuffer);
            assert(err, "src map setKernelArg");

            err = Cl.SetKernelArg(kernel, 2, intSize, imgfAccu.Stride);
            assert(err, "in stride setKernelArg");

            err = Cl.SetKernelArg(kernel, 3, intSize, imgfSrc.Stride);
            assert(err, "out stride setKernelArg");

            err = Cl.SetKernelArg(kernel, 4, floatSize, k);
            assert(err, "out stride setKernelArg");

            // write actual data into memory object
            Event clevent;
            err = Cl.EnqueueWriteBuffer<float>(_commandsQueue, accuMapBuffer, Bool.True, 0, imgfAccu.Size, imgfAccu._buf, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "write accu buffer");

            err = Cl.EnqueueWriteBuffer<float>(_commandsQueue, srcMapBuffer, Bool.True, 0, imgfSrc.Size, imgfSrc._buf, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "write src buffer");

            // execute
            err = Cl.EnqueueNDRangeKernel(_commandsQueue, kernel, 2,
                new[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 },  // offset
                new[] { new IntPtr(imgfAccu.W), new IntPtr(imgfAccu.H), (IntPtr)1 }, // range
                null, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "Cl.EnqueueNDRangeKernel");

            // sync
            Cl.Finish(_commandsQueue);

            // read from output memory object into actual buffer
            err = Cl.EnqueueReadBuffer<float>(_commandsQueue, accuMapBuffer, Bool.True, imgfAccu._buf, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "read output buffer");

            err = Cl.ReleaseMemObject(accuMapBuffer);
            assert(err, "releasing accuMapBuffer mem object");
            err = Cl.ReleaseMemObject(srcMapBuffer);
            assert(err, "releasing srcMapBuffer mem object");
        }
Esempio n. 12
0
        public FloatMap GetContrastMap(FloatMap inMap)
        {
            var      k      = _kernels["getContrastImg"];
            FloatMap outMap = new FloatMap(inMap.W, inMap.H);

            singlePass(k, inMap, outMap);

            return(outMap);
        }
Esempio n. 13
0
        // bleach!! should initialize two memory objects and ping-pong with them
        public FloatMap CapHoles(FloatMap inMap, int filterHalfSize)
        {
            for (int i = 0; i < 5; ++i) // since it's very difficult to set a bool (result of an or for each map element) from the kernel, let's just do it an arbitrary amount of times
            {
                inMap = capHoles(inMap, filterHalfSize);
            }

            return(inMap);
        }
Esempio n. 14
0
        public void singlePass(Kernel kernel, FloatMap inMap, FloatMap outMap)
        {
            var clInImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.Luminance, ChannelType.Float);

            IMem inputMapBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, clInImageFormat,
                                                   (IntPtr)inMap.W, (IntPtr)inMap.H, new IntPtr(inMap.Stride * sizeof(float)),
                                                   inMap._buf, out err);

            assert(err, "input img creation");


            IMem outputMapBuffer = Cl.CreateImage2D(_context, MemFlags.WriteOnly, clInImageFormat,
                                                    (IntPtr)outMap.W, (IntPtr)outMap.H, new IntPtr(outMap.Stride * sizeof(float)),
                                                    outMap._buf, out err);

            assert(err, "output img creation");


            // Set memory objects as parameters to kernel
            err = Cl.SetKernelArg(kernel, 0, intPtrSize, inputMapBuffer);
            assert(err, "input map setKernelArg");

            err = Cl.SetKernelArg(kernel, 1, intPtrSize, outputMapBuffer);
            assert(err, "output map setKernelArg");


            // write actual data into memory object
            IntPtr[] originPtr        = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 };               //x, y, z
            IntPtr[] inRegionPtr      = new IntPtr[] { (IntPtr)inMap.W, (IntPtr)inMap.H, (IntPtr)1 };   //x, y, z
            IntPtr[] outRegionPtr     = new IntPtr[] { (IntPtr)outMap.W, (IntPtr)outMap.H, (IntPtr)1 }; //x, y, z
            IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)outMap.W, (IntPtr)outMap.H, (IntPtr)1 };
            Event    clevent;

            //err = Cl.EnqueueWriteImage(_commandsQueue, inputMapBuffer, Bool.True, originPtr, inRegionPtr, (IntPtr)0, (IntPtr)0, inMap._buf, 0, null, out clevent);
            //clevent.Dispose();
            //assert(err, "write input img");

            // execute
            err = Cl.EnqueueNDRangeKernel(_commandsQueue, kernel, 2,
                                          originPtr,
                                          workGroupSizePtr,
                                          null, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "Cl.EnqueueNDRangeKernel");

            // sync
            Cl.Finish(_commandsQueue);

            // read from output memory object into actual buffer
            err = Cl.EnqueueReadImage(_commandsQueue, outputMapBuffer, Bool.True, originPtr, outRegionPtr, new IntPtr(outMap.Stride * sizeof(float)), (IntPtr)0, outMap._buf, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "read output buffer");

            Cl.ReleaseMemObject(inputMapBuffer);
            Cl.ReleaseMemObject(outputMapBuffer);
        }
Esempio n. 15
0
        // Caps holes taking values (weighted by distance) from neighborhood
        // for interpolation; filter can cap holes as large as filterHalfSize*2;
        // multiple passes could be needed.
        public static FloatMap CapHoles(FloatMap imgfIn, int filterHalfSize)
        {
            bool thereAreStillHoles = true;

            while (thereAreStillHoles)
            {
                imgfIn = MapUtils.capHoles(imgfIn, filterHalfSize, out thereAreStillHoles);
            }
            return(imgfIn);
        }
Esempio n. 16
0
        public FloatMap HalfMap(FloatMap inMap)
        {
            var      k1     = _kernels["halfSizeImgH"];
            var      k2     = _kernels["halfSizeImgV"];
            FloatMap outMap = new FloatMap(inMap.W / 2, inMap.H / 2);

            doublePass(k1, k2, inMap, outMap, inMap.W / 2, inMap.H);

            return(outMap);
        }
Esempio n. 17
0
        public FloatMap QuickBlurMap(FloatMap inMap)
        {
            var      k1     = _kernels["quickBlurImgH"];
            var      k2     = _kernels["quickBlurImgV"];
            FloatMap outMap = new FloatMap(inMap.W, inMap.H);

            doublePass(k1, k2, inMap, outMap);

            return(outMap);
        }
Esempio n. 18
0
        public FloatMap ResizeMap(FloatMap imgfIn, int dstW, int dstH)
        {
            int srcH = imgfIn.H;
            int srcW = imgfIn.W;

            float xk = (float)srcW / (float)dstW;
            float yk = (float)srcH / (float)dstH;

            return(invokeMapKernel(_kernels["upsizel"], imgfIn, dstW, dstH, dstW, dstH, 0, 0, xk, yk));
        }
Esempio n. 19
0
        FloatMap convolve(FloatMap imgfIn, FloatMap filter)
        {
            int filterSize     = filter.W;
            int filterHalfSize = filterSize / 2;

            int h = imgfIn.H;
            int w = imgfIn.W;

            var imgfOut = new FloatMap(w, h);

            for (int y = 0; y < h; ++y)
            {
                for (int x = 0; x < w; ++x)
                {
                    // if point in [x,y] == -1 then cap that:
                    // foreach a,b from x-filtersize to x+filtersize (same for y)
                    // if that point is != -1 accumulate that * weight[a,b], accumulate weight[a,b]

                    float accu  = 0;
                    float wAccu = 0;
                    int   cMinX = x - filterHalfSize;
                    int   cMinY = y - filterHalfSize;
                    int   minX  = Math.Max(0, cMinX);
                    int   minY  = Math.Max(0, cMinY);
                    int   xOffs = minX - cMinX;
                    int   yOffs = minY - cMinY;
                    int   maxX  = Math.Min(w, x + filterHalfSize);
                    int   maxY  = Math.Min(h, y + filterHalfSize);
                    for (int b = minY, fb = yOffs; b < maxY; ++b, ++fb)
                    {
                        for (int a = minX, fa = xOffs; a < maxX; ++a, ++fa)
                        {
                            float v = imgfIn[a, b];
                            if (v >= 0)
                            {
                                float weight = filter[fa, fb];
                                wAccu += weight;
                                accu  += v * weight;
                            }
                        }
                    }

                    if (wAccu != 0)
                    {
                        imgfOut[x, y] = accu / wAccu;
                    }
                    else
                    {
                        imgfOut[x, y] = -1;
                    }
                }
            }

            return(imgfOut);
        }
Esempio n. 20
0
        // Caps holes taking values (weighted by distance) from neighborhood
        // for interpolation; filter can cap holes as large as filterHalfSize*2;
        // multiple passes could be needed.
        public FloatMap CapHoles(FloatMap imgfIn, int filterHalfSize)
        {
            var  mask = getDistanceWeightMap(filterHalfSize);
            bool thereAreStillHoles = true;

            while (thereAreStillHoles)
            {
                imgfIn = convolvec(imgfIn, mask, out thereAreStillHoles);
            }
            return(imgfIn);
        }
Esempio n. 21
0
        public FloatMap CapHoles(FloatMap imgfIn, int filterHalfSize)
        {
            var mask   = getDistanceWeightMap(filterHalfSize);
            var kernel = _kernels["capHoles"];

            for (int i = 0; i < 5; ++i) // since it's very difficult to set a bool (result of an or for each map element) from the kernel, let's just do it an arbitrary amount of times
            {
                imgfIn = invokeConvolve(kernel, imgfIn, mask);
            }
            return(imgfIn);
        }
Esempio n. 22
0
        public FloatMap SpikesFilter(FloatMap inMap, float treshold)
        {
            var      k      = _kernels["quickSpikesFilterImg"];
            FloatMap outMap = new FloatMap(inMap.W, inMap.H);

            err = Cl.SetKernelArg(k, 2, floatSize, treshold);
            assert(err, "treshold, setKernelArg");

            singlePass(k, inMap, outMap);

            return(outMap);
        }
Esempio n. 23
0
        // Creates the blue-red depth map
        public static Bitmap Map2BmpDepthMap(FloatMap imgf, float k, int count)
        {
            int h      = imgf.H;
            int w      = imgf.W;
            int stride = imgf.Stride;

            var bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);

            BitmapData dstData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            int pixelSize = 4;

            unsafe
            {
                var   dstStride    = dstData.Stride;
                byte *dstRow       = (byte *)dstData.Scan0;
                int   srcLineStart = 0;
                for (int y = 0; y < h; ++y)
                {
                    int srcIdx = srcLineStart;
                    int wb     = w * pixelSize;
                    for (int x = 0; x < wb; x += 4)
                    {
                        float v = imgf[srcIdx];
                        v = v < 0 ? -1 : 255 - v * 255 / count;

                        if (v >= 0)
                        {
                            byte b = (byte)Math.Min(255, Math.Max((v * k), 0));
                            dstRow[x]     = b;
                            dstRow[x + 1] = 0;
                            dstRow[x + 2] = (byte)(255 - b);
                            dstRow[x + 3] = 255;
                        }
                        else
                        {
                            dstRow[x]     = 0;
                            dstRow[x + 1] = 0;
                            dstRow[x + 2] = 0;
                            dstRow[x + 3] = 255;
                        }
                        ++srcIdx;
                    }
                    srcLineStart += stride;
                    dstRow       += dstStride;
                }
            }

            bmp.UnlockBits(dstData);
            return(bmp);
        }
Esempio n. 24
0
        // Converts from bitmap 32bpp ARGB to float map
        public FloatMap Bmp2Map(Bitmap bmp)
        {
            var w = bmp.Width;
            var h = bmp.Height;

            Bitmap tmp = null;

            if (bmp.PixelFormat != PixelFormat.Format32bppArgb)
            {
                bmp = bmp.Clone(new Rectangle(0, 0, w, h), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                tmp = bmp;
            }

            var imgf   = new FloatMap(w, h);
            int stride = imgf.Stride;

            int pixelSize = 4;

            BitmapData srcData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                byte *srcRow    = (byte *)srcData.Scan0;
                int   srcStride = srcData.Stride;

                int dstLineStart = 0;
                for (int y = 0; y < h; ++y)
                {
                    int dstIdx = dstLineStart;
                    int wb     = w * pixelSize;
                    for (int x = 0; x < wb; x += pixelSize)
                    {
                        // considers Y component; in future, it would be nice to let user choose between single channels, luma, average, ...
                        imgf[dstIdx] = getLuminance(srcRow[x + 0], srcRow[x + 1], srcRow[x + 2]); // +3 is alpha
                        ++dstIdx;
                    }
                    dstLineStart += stride;
                    srcRow       += srcStride;
                }
            }

            bmp.UnlockBits(srcData);

            if (tmp != null)
            {
                tmp.Dispose(); // disposing our cloned copy... caller is responsible to dispose original bmp
            }

            return(imgf);
        }
Esempio n. 25
0
        // Converts from bitmap 32bpp ARGB to float map
        public FloatMap Bmp2Map(Bitmap bmp)
        {
            var w = bmp.Width;
            var h = bmp.Height;

            Bitmap tmp = null;

            if (bmp.PixelFormat != PixelFormat.Format32bppArgb)
            {
                bmp = bmp.Clone(new Rectangle(0, 0, w, h), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                tmp = bmp;
            }

            var imgf = new FloatMap(w, h);
            int stride = imgf.Stride;

            int pixelSize = 4;

            BitmapData srcData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            unsafe
            {
                byte* srcRow = (byte*)srcData.Scan0;
                int srcStride = srcData.Stride;

                int dstLineStart = 0;
                for (int y = 0; y < h; ++y)
                {
                    int dstIdx = dstLineStart;
                    int wb = w * pixelSize;
                    for (int x = 0; x < wb; x += pixelSize)
                    {
                        // considers Y component; in future, it would be nice to let user choose between single channels, luma, average, ...
                        imgf[dstIdx] = getLuminance(srcRow[x + 0], srcRow[x + 1], srcRow[x + 2]); // +3 is alpha
                        ++dstIdx;
                    }
                    dstLineStart += stride;
                    srcRow += srcStride;
                }
            }

            bmp.UnlockBits(srcData);

            if (tmp != null)
            {
                tmp.Dispose(); // disposing our cloned copy... caller is responsible to dispose original bmp
            }

            return imgf;
        }
Esempio n. 26
0
        // again: should initialize two memory objects and ping-pong with them (but this method is not crytical, after all)
        public float GetMapMax(FloatMap inMap)
        {
            var      k1     = _kernels["maxReduceImgH"];
            var      k2     = _kernels["maxReduceImgV"];
            FloatMap outMap = new FloatMap((int)Math.Ceiling(inMap.W / 2.0f), (int)Math.Ceiling(inMap.H / 2.0f));

            while (true)
            {
                doublePass(k1, k2, inMap, outMap, (int)Math.Ceiling(inMap.W / 2.0f), inMap.H);
                if ((outMap.W == 1) && (outMap.W == 1))
                {
                    return(outMap[0, 0]);
                }
                inMap  = outMap;
                outMap = new FloatMap((int)Math.Ceiling(inMap.W / 2.0f), (int)Math.Ceiling(inMap.H / 2.0f));
            }
        }
Esempio n. 27
0
        FloatMap getMaxMap()
        {
            int h = _imgfs[0].H;
            int w = _imgfs[0].W;

            FloatMap imgfOut = new FloatMap(w, h);

            for (int y = 0; y < h; ++y)
            {
                for (int x = 0; x < w; ++x)
                {
                    float v = getMaxIdx(x, y);
                    imgfOut[x, y] = v;// < 0 ? -1 : 255 - v * 255 / _imgfs.Count; // MOVED into map2BmpDepth
                }
            }

            return(imgfOut);
        }
Esempio n. 28
0
        public FloatMap GetMultiResContrastEvaluation(FloatMap imgfIn, int subSamples)
        {
            int   h = imgfIn.H;
            int   w = imgfIn.W;
            float k = 1;

            FloatMap contr = new FloatMap(w, h);
            var      img   = imgfIn;

            for (int i = 0; i < subSamples; ++i)
            {
                var rc = ResizeMap(QuickBlurMap(GetContrastMap(img)), w, h);
                Accumulate(contr, rc, k);
                k  *= 0.5f;
                img = HalfMap(img);
            }
            return(contr);
        }
Esempio n. 29
0
        // Computes some sort of resolution independant contrast defined as follows
        // (don't know yet if it's ok or not)
        // compute contrast map on input map, then
        // downscales the image, gets the contrast map again, scales up contrast map to
        // original size and accumulates in original input map. Repeat several times.
        // Arguably, it could be computed more efficiently, but i don't care
        // optimizing code that will still have to be changed several times.
        public FloatMap GetMultiResContrastEvaluation(FloatMap imgfIn, int subSamples)
        {
            int   h = imgfIn.H;
            int   w = imgfIn.W;
            float k = 1;

            FloatMap contr = new FloatMap(w, h);
            var      img   = imgfIn;

            for (int i = 0; i < subSamples; ++i)
            {
                var rc = ResizeMap(QuickBlurMap(GetContrastMap(img)), w, h);
                //var rc = DoubleImg(BlurImg(GetContrImg(img)), i); // <-- multi step reduction would still be first choice with openCl
                Accumulate(contr, rc, k);
                k  *= 0.5f;
                img = HalfMap(img);
            }
            return(contr);
        }
Esempio n. 30
0
        public FloatMap ResizeMap(FloatMap inMap, int dstW, int dstH)
        {
            float xk = (float)inMap.W / (float)dstW;
            float yk = (float)inMap.H / (float)dstH;

            FloatMap outMap = new FloatMap(dstW, dstH);

            var k = _kernels["upsizeImg"];

            err = Cl.SetKernelArg(k, 2, floatSize, xk);
            assert(err, "xk setKernelArg");

            err = Cl.SetKernelArg(k, 3, floatSize, yk);
            assert(err, "yk setKernelArg");

            singlePass(k, inMap, outMap);

            return(outMap);
        }
Esempio n. 31
0
        private FloatMap getDistanceWeightMap(int filterHalfSize)
        {
            int      size = filterHalfSize * 2 + 1;
            int      sup  = size - 1;
            FloatMap wMap = new FloatMap(size, size);

            for (int y = 0; y < filterHalfSize; ++y)
            {
                for (int x = 0; x <= filterHalfSize; ++x)
                {
                    float dx = (filterHalfSize - x);
                    float dy = (filterHalfSize - y);
                    wMap[x, y] = wMap[y, sup - x] = wMap[sup - y, x] = wMap[sup - x, sup - y] = (float)(1.0 / Math.Sqrt(dx * dx + dy * dy));
                }
            }

            wMap[filterHalfSize, filterHalfSize] = 0;

            return(wMap);
        }
Esempio n. 32
0
        public FloatMap GaussianBlur(FloatMap inMap, float sigma)
        {
            var      k      = _kernels["convolveImg"];
            FloatMap outMap = new FloatMap(inMap.W, inMap.H);

            FloatMap mask = createBlurMask(sigma);

            IMem <float> maskBuf = Cl.CreateBuffer <float>(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, mask._buf, out err);

            assert(err, "capholes mask, mem object creation");

            err = Cl.SetKernelArg(k, 2, intPtrSize, maskBuf);
            assert(err, "capholes mask, setKernelArg");

            err = Cl.SetKernelArg(k, 3, intSize, (mask.W - 1) / 2);
            assert(err, "capholes mask, setKernelArg");

            singlePass(k, inMap, outMap);

            return(outMap);
        }
Esempio n. 33
0
        // Sets each pixel P in accumulation map to PValue + QValue,
        // where Q is corresponding pixel in the other provided map
        public void Accumulate(FloatMap imgfInAccu, FloatMap imgfIn, float k)
        {
            int h = imgfInAccu.H;
            int w = imgfInAccu.W;
            int stride = imgfInAccu.Stride;

            if ((imgfIn.H != h) || (imgfIn.W != w))
            {
                throw new Exception("Images must have same size!");
            }

            int lineStart = 0;
            for (int y = 0; y < h; ++y)
            {
                var i = lineStart;
                for (int x = 0; x < w; ++x)
                {
                    imgfInAccu[i] = imgfInAccu[i] + imgfIn[i] * k;
                    i += 1;
                }
                lineStart += stride;
            }
        }
Esempio n. 34
0
        // Returns maximum value in a map;
        // used to show normalized bitmaps
        public static float GetMapMax(FloatMap imgfIn)
        {
            int h = imgfIn.H;
            int w = imgfIn.W;
            int stride = imgfIn.Stride;

            float max = float.MinValue;
            float min = float.MaxValue;

            int lineStart = 0;
            for (int y = 0; y < h; ++y)
            {
                var i = lineStart;
                for (int x = 0; x < w; ++x)
                {
                    var v = imgfIn[i];
                    if (v > max)
                    {
                        max = v;
                    }

                    // debug only
                    if ((v > 0) && (v < min))
                    {
                        min = v;
                    }

                    i += 1;
                }
                lineStart += stride;
            }

            Console.WriteLine("\n\nmin: {0}\nmax: {1}\n\n", min, max);

            return max;
        }
Esempio n. 35
0
        // Returns a map of focus ranks, defined as follows:
        //  for each pixel C of input image (but borders)
        //      for each pixel N of center's neighborhood
        //          accumulate |C-P| * W where W is a weight depending on distance between C and N
        public static FloatMap GetContrastMap(FloatMap imgfIn)
        {
            const float k1 = 0.104167f;
            const float k2 = 0.145833f;

            int h = imgfIn.H;
            int w = imgfIn.W;
            int stride = imgfIn.Stride;

            var contrImgfs = new FloatMap(w, h);

            int lineStart = stride;
            for (int y = 1; y < h - 1; ++y)
            {
                var i = lineStart + 1;
                for (int x = 1; x < w - 2; ++x) // -2 ?????
                {
                    var c = imgfIn[i];

                    // TODO: Optimize with scanlines
                    contrImgfs[i] = (Math.Abs(c - imgfIn[i + stride]) + Math.Abs(c - imgfIn[i - stride]) + Math.Abs(c - imgfIn[i + 1]) + Math.Abs(c - imgfIn[i - 1])) * k2 +
                                    (Math.Abs(c - imgfIn[i + stride + 1]) + Math.Abs(c - imgfIn[i + stride - 1]) + Math.Abs(c - imgfIn[i - stride + 1]) + Math.Abs(c - imgfIn[i - stride - 1])) * k1;
                    i += 1;
                }
                lineStart += stride;
            }
            return contrImgfs;
        }
Esempio n. 36
0
        public void singlePass(Kernel kernel, FloatMap inMap, FloatMap outMap)
        {
            var clInImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.Luminance, ChannelType.Float);

            IMem inputMapBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, clInImageFormat,
                                                (IntPtr)inMap.W, (IntPtr)inMap.H, new IntPtr(inMap.Stride * sizeof(float)),
                                                inMap._buf, out err);

            assert(err, "input img creation");

            IMem outputMapBuffer = Cl.CreateImage2D(_context, MemFlags.WriteOnly, clInImageFormat,
                                                (IntPtr)outMap.W, (IntPtr)outMap.H, new IntPtr(outMap.Stride * sizeof(float)),
                                                outMap._buf, out err);

            assert(err, "output img creation");

            // Set memory objects as parameters to kernel
            err = Cl.SetKernelArg(kernel, 0, intPtrSize, inputMapBuffer);
            assert(err, "input map setKernelArg");

            err = Cl.SetKernelArg(kernel, 1, intPtrSize, outputMapBuffer);
            assert(err, "output map setKernelArg");

            // write actual data into memory object
            IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 };    //x, y, z
            IntPtr[] inRegionPtr = new IntPtr[] { (IntPtr)inMap.W, (IntPtr)inMap.H, (IntPtr)1 };    //x, y, z
            IntPtr[] outRegionPtr = new IntPtr[] { (IntPtr)outMap.W, (IntPtr)outMap.H, (IntPtr)1 };    //x, y, z
            IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)outMap.W, (IntPtr)outMap.H, (IntPtr)1 };
            Event clevent;
            //err = Cl.EnqueueWriteImage(_commandsQueue, inputMapBuffer, Bool.True, originPtr, inRegionPtr, (IntPtr)0, (IntPtr)0, inMap._buf, 0, null, out clevent);
            //clevent.Dispose();
            //assert(err, "write input img");

            // execute
            err = Cl.EnqueueNDRangeKernel(_commandsQueue, kernel, 2,
                originPtr,
                workGroupSizePtr,
                null, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "Cl.EnqueueNDRangeKernel");

            // sync
            Cl.Finish(_commandsQueue);

            // read from output memory object into actual buffer
            err = Cl.EnqueueReadImage(_commandsQueue, outputMapBuffer, Bool.True, originPtr, outRegionPtr, new IntPtr(outMap.Stride * sizeof(float)), (IntPtr)0, outMap._buf, 0, null, out clevent);
            clevent.Dispose();
            assert(err, "read output buffer");

            Cl.ReleaseMemObject(inputMapBuffer);
            Cl.ReleaseMemObject(outputMapBuffer);
        }
Esempio n. 37
0
        static FloatMap convolute(FloatMap imgfIn, FloatMap filter, out bool thereAreStillHoles)
        {
            thereAreStillHoles = false;
            int filterSize = filter.W;
            int filterHalfSize = filterSize / 2;

            int h = imgfIn.H;
            int w = imgfIn.W;

            var imgfOut = new FloatMap(w, h);

            for (int y = 0; y < h ; ++y)
            {
                for (int x = 0; x < w; ++x)
                {
                    // if point in [x,y] == -1 then cap that:
                    // foreach a,b from x-filtersize to x+filtersize (same for y)
                    // if that point is != -1 accumulate that * weight[a,b], accumulate weight[a,b]

                    if (imgfIn[x, y] < 0) // --> need to cap
                    {
                        float accu = 0;
                        float wAccu = 0;
                        int cMinX = x - filterHalfSize;
                        int cMinY = y - filterHalfSize;
                        int minX = Math.Max(0, cMinX);
                        int minY = Math.Max(0, cMinY);
                        int xOffs = minX - cMinX;
                        int yOffs = minY - cMinY;
                        int maxX = Math.Min(w, x + filterHalfSize);
                        int maxY = Math.Min(h, y + filterHalfSize);
                        for (int b = minY, fb = yOffs; b < maxY; ++b, ++fb)
                        {
                            for (int a = minX, fa = xOffs; a < maxX; ++a, ++fa)
                            {
                                float v = imgfIn[a, b];
                                if (v >= 0)
                                {
                                    float weight = filter[fa, fb];
                                    wAccu += weight;
                                    accu += v * weight;
                                }
                            }
                        }

                        if (wAccu != 0)
                        {
                            imgfOut[x, y] = accu / wAccu;
                        }
                        else
                        {
                            imgfOut[x, y] = -1;
                            thereAreStillHoles = true;
                        }
                    }
                    else
                    {
                        imgfOut[x, y] = imgfIn[x,y];
                    }

                }
            }

            return imgfOut;
        }
Esempio n. 38
0
        // This is some sort of median filter, with the difference that
        // "outlier" values are just invalidated and left
        // for another step to be replaced with appropriate value
        // (this additional interpolation step still doesn't exist, though)
        public static FloatMap SpikesFilter(FloatMap imgfIn, float treshold)
        {
            int h = imgfIn.H;
            int w = imgfIn.W;
            int stride = imgfIn.Stride;

            var imgfOut = new FloatMap(w, h);

            const float k = 0.70710678118654752440084436210485f; // w = 1/sqrt(2); lazy me, i just compied result of w/wtot from calc... i know we don't have that much detail in singles

            // TODO: Should handle -1s correctly here, sooner or later XD

            // copy borders directly from src to dst
            int yLin = (h-1) * stride;
            for (int x = 0; x < w; ++x)
            {
                imgfOut[x] = imgfIn[x];
                imgfOut[x + yLin] = imgfIn[x + yLin];
            }

            yLin = 0;
            for (int y = 0; y < h; ++y)
            {
                imgfOut[yLin] = imgfIn[yLin];
                imgfOut[yLin + stride - 1] = imgfIn[yLin + stride - 1];
                yLin += stride;
            }

            // visit each pixel not belonging to borders;
            // for each one, consider its value and the average value
            // of its neighborhood (weighted proportionally to distance
            // from center pixel): if |value-average|>treshold
            // pixel is invalidated (=-1)
            float neighborhoodWeight;
            float neighborhoodAccu;
            float v;
            int lineStart = stride;
            for (int y = 1; y < h - 1; ++y)
            {
                int i = lineStart + 1; ;
                for (int x = 1; x < w - 1; ++x)
                {
                    neighborhoodWeight = 0;
                    neighborhoodAccu = 0;

                    // considering neighborhood pixels separately to correctly handle -1s

                    v = imgfIn[i + stride];
                    if (v > 0)
                    {
                        neighborhoodAccu += v;
                        neighborhoodWeight += 1;
                    }

                    v = imgfIn[i - stride];
                    if (v > 0)
                    {
                        neighborhoodAccu += v;
                        neighborhoodWeight += 1;
                    }

                    v = imgfIn[i + 1];
                    if (v > 0)
                    {
                        neighborhoodAccu += v;
                        neighborhoodWeight += 1;
                    }

                    v = imgfIn[i -1];
                    if (v > 0)
                    {
                        neighborhoodAccu += v;
                        neighborhoodWeight += 1;
                    }

                    v = imgfIn[i + stride + 1];
                    if (v > 0)
                    {
                        neighborhoodAccu += v * k;
                        neighborhoodWeight += k;
                    }

                    v = imgfIn[i + stride -1];
                    if (v > 0)
                    {
                        neighborhoodAccu += v * k;
                        neighborhoodWeight += k;
                    }

                    v = imgfIn[i - stride + 1];
                    if (v > 0)
                    {
                        neighborhoodAccu += v * k;
                        neighborhoodWeight += k;
                    }

                    v = imgfIn[i - stride - 1];
                    if (v > 0)
                    {
                        neighborhoodAccu += v * k;
                        neighborhoodWeight += k;
                    }

                    var d = Math.Abs(imgfIn[i] - (neighborhoodAccu / neighborhoodWeight));

                    imgfOut[i] = ((d > treshold) ? -1 : imgfIn[i]); // pixel value is just invalidated. A further step will take care of interpolation for missing value

                    ++i;
                }
                lineStart += stride;
            }
            return imgfOut;
        }
Esempio n. 39
0
        // Converts from float map to bitmap 32bpp ARGB
        public static Bitmap Map2Bmp(FloatMap imgf, float k)
        {
            int h = imgf.H;
            int w = imgf.W;
            int stride = imgf.Stride;

            var bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);

            BitmapData dstData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            int pixelSize = 4;

            unsafe
            {
                var dstStride = dstData.Stride;
                byte* dstRow = (byte*)dstData.Scan0;
                int srcLineStart = 0;
                for (int y = 0; y < h; ++y)
                {
                    int srcIdx = srcLineStart;
                    int wb = w * pixelSize;
                    for (int x = 0; x < wb; x+=pixelSize)
                    {
                        byte b = (byte)(imgf[srcIdx] * k);
                        dstRow[x] = b;
                        dstRow[x + 1] = b;
                        dstRow[x + 2] = b;
                        dstRow[x + 3] = 255;
                        ++srcIdx;
                    }
                    srcLineStart += stride;
                    dstRow += dstStride;
                }
            }

            bmp.UnlockBits(dstData);
            return bmp;
        }
Esempio n. 40
0
 // Returns an image which sizes are each 1/2^times the original value;
 // will be probably replaced with reduction/expansion-style OpenCl operation
 public static FloatMap HalfMap(FloatMap imgfIn, int times)
 {
     for (int i = 0; i < times; ++i)
     {
         imgfIn = HalfMap(imgfIn);
     }
     return imgfIn;
 }
Esempio n. 41
0
 public FloatMap GaussianBlur(FloatMap imgfIn, float sigma)
 {
     FloatMap blurMask = createBlurMask(sigma);
     return convolve(imgfIn, blurMask);
 }
Esempio n. 42
0
 // Returns an image which sizes are each 2^times the original value;
 // will be probably replaced with reduction/expansion-style
 // OpenCl operation
 public FloatMap DoubleMap(FloatMap imgfIn, int times)
 {
     for (int i = 0; i < times; ++i)
     {
         imgfIn = DoubleMap(imgfIn);
     }
     return imgfIn;
 }
Esempio n. 43
0
        public FloatMap SpikesFilter(FloatMap inMap, float treshold)
        {
            var k = _kernels["quickSpikesFilterImg"];
            FloatMap outMap = new FloatMap(inMap.W, inMap.H);

            err = Cl.SetKernelArg(k, 2, floatSize, treshold);
            assert(err, "treshold, setKernelArg");

            singlePass(k, inMap, outMap);

            return outMap;
        }
Esempio n. 44
0
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            if ((_fileNames == null) || (_fileNames.Length <= 3))
            {
                return;
            }

            _imgfs.Clear();

            int fileCount = _fileNames.Length;

            float progressStep = 100.0f / (fileCount * 2.0f);
            float progress = 0;

            backgroundWorker1.ReportProgress((int)progress,"converting");

            // for each selected file
            for (int fileIdx = 0; fileIdx < fileCount; ++fileIdx)
            {
                string fileName = _fileNames[fileIdx];

                // load bitmap
                using (var _bmp = new Bitmap(fileName))
                {
                    if (fileIdx == 0)
                    {
                        _h = _bmp.Height;
                        _w = _bmp.Width;
                    }
                    else
                    {

                        if ((_h != _bmp.Height) || (_w != _bmp.Width))
                        {
                            MessageBox.Show("Images must have same size!");
                            return;
                        }
                    }

                    FloatMap imgf;

                    // get luminance map
                    imgf = MapUtils.HalfMap(MapUtils.Bmp2Map(_bmp), PreShrinkTimes);

                    _imgfs.Add(imgf);
                }

                // update and report progress
                progress += progressStep;
                backgroundWorker1.ReportProgress((int)progress);

                // check for cancellation
                if (backgroundWorker1.CancellationPending)
                {
                    return;
                }
            }

            List<FloatMap> newImgfs = new List<FloatMap>();

            backgroundWorker1.ReportProgress((int)progress, "getting contrast");

            // for each luminance map
            foreach (var imgf in _imgfs)
            {
                // get contrast, then shrink result (averaging pixels)
                FloatMap newImgf = MapUtils.HalfMap(MapUtils.GetMultiResContrastEvaluation(imgf, MultiResSteps), ShrinkContrastTimes);

                newImgfs.Add(newImgf);

                // update and report progress
                progress += progressStep;
                backgroundWorker1.ReportProgress((int)progress);

                // check for cancellation
                if (backgroundWorker1.CancellationPending)
                {
                    return;
                }
            }

            _imgfs = newImgfs;

            smoothDepth(); smoothDepth();

            _maxMap = getMaxMap();

            // smooth
            for (int i = 0; i < BlurTimes; ++i)
            {
                _maxMap = MapUtils.GaussianBlur(_maxMap, BlurSigma);
            }

            // filter out spikes
            _maxMap = MapUtils.SpikesFilter(_maxMap, SpikeFilterTreshold);

            // cap holes
            _maxMap = MapUtils.CapHoles(_maxMap, CapHolesFilterEmisize);

            // TODO: correct the bell-distorsion

            savePLY();

            saveObj();
        }
Esempio n. 45
0
        private static FloatMap getDistanceWeightMap(int filterHalfSize)
        {
            int size = filterHalfSize * 2 + 1;
            int sup = size - 1;
            FloatMap wMap = new FloatMap(size, size);
            for (int y = 0; y < filterHalfSize; ++y)
            {
                for (int x = 0; x <= filterHalfSize; ++x)
                {
                    float dx = (filterHalfSize - x);
                    float dy = (filterHalfSize - y);
                    wMap[x, y] = wMap[y, sup - x] = wMap[sup - y, x] = wMap[sup - x, sup - y] = (float)(1.0/Math.Sqrt(dx * dx + dy * dy));
                }
            }

            wMap[filterHalfSize, filterHalfSize] = 0;

            return wMap;
        }
Esempio n. 46
0
        // Computes some sort of resolution independant contrast defined as follows
        // (don't know yet if it's ok or not)
        // compute contrast map on input map, then
        // downscales the image, gets the contrast map again, scales up contrast map to
        // original size and accumulates in original input map. Repeat several times.
        // Arguably, it could be computed more efficiently, but i don't care
        // optimizing code that will still have to be changed several times.
        public static FloatMap GetMultiResContrastEvaluation(FloatMap imgfIn, int subSamples)
        {
            int h = imgfIn.H;
            int w = imgfIn.W;
            float k = 1;

            FloatMap contr = new FloatMap(w, h);
            var img = imgfIn;
            for (int i = 0; i < subSamples; ++i)
            {
                var rc = ResizeMap(FastBlurMap(GetContrastMap(img)), w, h);
                //var rc = DoubleImg(BlurImg(GetContrImg(img)), i); // <-- multi step reduction would still be first choice with openCl
                Accumulate(contr, rc, k);
                k *= 0.5f;
                img = HalfMap(img);
            }
            return contr;
        }
Esempio n. 47
0
        // Code has been just replicated from SpikesFilter...
        // this stuff is just helping me experiment
        // and won't be mantained "nice"
        // SpikesFilter doesn't just call GetSpike
        // for performance reasons, too
        public static float GetSpikeHeight(FloatMap imgfIn, int x, int y)
        {
            const float k = 0.70710678118654752440084436210485f; // w = 1/sqrt(2); lazy me, i just compied result of w/wtot from calc... i know we don't have that much detail in singles

            int h = imgfIn.H;
            int w = imgfIn.W;
            int stride = imgfIn.Stride;

            int lineStart = y * stride;

            int i = y * stride + x;

            float neighborhoodWeight = 0;
            float neighborhoodAccu = 0;
            float v;
            // considering neighborhood pixels separately to correctly handle -1s

            v = imgfIn[i + stride];
            if (v > 0)
            {
                neighborhoodAccu += v;
                neighborhoodWeight += 1;
            }

            v = imgfIn[i - stride];
            if (v > 0)
            {
                neighborhoodAccu += v;
                neighborhoodWeight += 1;
            }

            v = imgfIn[i + 1];
            if (v > 0)
            {
                neighborhoodAccu += v;
                neighborhoodWeight += 1;
            }

            v = imgfIn[i - 1];
            if (v > 0)
            {
                neighborhoodAccu += v;
                neighborhoodWeight += 1;
            }

            v = imgfIn[i + stride + 1];
            if (v > 0)
            {
                neighborhoodAccu += v * k;
                neighborhoodWeight += k;
            }

            v = imgfIn[i + stride - 1];
            if (v > 0)
            {
                neighborhoodAccu += v * k;
                neighborhoodWeight += k;
            }

            v = imgfIn[i - stride + 1];
            if (v > 0)
            {
                neighborhoodAccu += v * k;
                neighborhoodWeight += k;
            }

            v = imgfIn[i - stride - 1];
            if (v > 0)
            {
                neighborhoodAccu += v * k;
                neighborhoodWeight += k;
            }

            var d = Math.Abs(imgfIn[i] - (neighborhoodAccu / neighborhoodWeight));

            return d;
        }
Esempio n. 48
0
 // Caps holes taking values (weighted by distance) from neighborhood
 // for interpolation; filter can cap holes as large as filterHalfSize*2;
 // multiple passes could be needed.
 public static FloatMap CapHoles(FloatMap imgfIn, int filterHalfSize)
 {
     bool thereAreStillHoles = true;
     while (thereAreStillHoles)
     {
         imgfIn = MapUtils.capHoles(imgfIn, filterHalfSize, out thereAreStillHoles);
     }
     return imgfIn;
 }
Esempio n. 49
0
        // Returns an image which sizes are each half the original value;
        // will be probably replaced with reduction/expansion-style OpenCl operation
        public static FloatMap HalfMap(FloatMap imgfIn)
        {
            int h = imgfIn.H;
            int w = imgfIn.W;
            int stride = imgfIn.Stride;

            int hh = h >> 1;
            int hw = w >> 1;

            var imgfOut = new FloatMap(hw, hh);

            int hStride = imgfOut.Stride;

            int lineStart = 0;
            int hLineStart = 0;
            for (int y = 0; y < hh; ++y)
            {
                int i = lineStart;
                int hi = hLineStart;
                for (int x = 0; x < hw; ++x)
                {
                    imgfOut[hi] = (imgfIn[i] + imgfIn[i + stride] + imgfIn[i + 1] + imgfIn[i + stride + 1]) * 0.25f;
                    i += 2;
                    ++hi;
                }
                lineStart += stride << 1;
                hLineStart += hStride;
            }
            return imgfOut;
        }
Esempio n. 50
0
        // returns an image which sizes are each double the original value;
        // will be probably replaced with reduction/expansion-style
        // OpenCl operation
        public static FloatMap DoubleMap(FloatMap imgfIn)
        {
            int h = imgfIn.H;
            int w = imgfIn.W;

            int dh = h * 2;
            int dw = w * 2;

            var imgfOut = new FloatMap(dw, dh);
            int dstStride = imgfOut.Stride;

            float dx = 0, dy = 0;

            int dLineStart = 0;
            for (int y = 0; y < dh - 2; ++y)
            {
                dx = 0;
                int i = dLineStart;
                for (int x = 0; x < dw - 2; ++x)
                {
                    imgfOut[i] = imgfIn[dx, dy];
                    dx += 0.5f;
                    ++i;
                }
                dy += 0.5f;
                dLineStart += dstStride;
            }
            return imgfOut;
        }
Esempio n. 51
0
        // Creates the blue-red depth map
        public static Bitmap Map2BmpDepthMap(FloatMap imgf, float k, int count)
        {
            int h = imgf.H;
            int w = imgf.W;
            int stride = imgf.Stride;

            var bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);

            BitmapData dstData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            int pixelSize = 4;

            unsafe
            {
                var dstStride = dstData.Stride;
                byte* dstRow = (byte*)dstData.Scan0;
                int srcLineStart = 0;
                for (int y = 0; y < h; ++y)
                {
                    int srcIdx = srcLineStart;
                    int wb = w * pixelSize;
                    for (int x = 0; x < wb; x+=4)
                    {
                        float v = imgf[srcIdx];
                        v = v < 0 ? -1 : 255 - v * 255 / count;

                        if (v >= 0)
                        {
                            byte b = (byte)Math.Min(255, Math.Max((v * k), 0));
                            dstRow[x] = b;
                            dstRow[x + 1] = 0;
                            dstRow[x + 2] = (byte)(255 - b);
                            dstRow[x + 3] = 255;
                        }
                        else
                        {
                            dstRow[x] = 0;
                            dstRow[x + 1] = 0;
                            dstRow[x + 2] = 0;
                            dstRow[x + 3] = 255;
                        }
                        ++srcIdx;
                    }
                    srcLineStart += stride;
                    dstRow += dstStride;
                }
            }

            bmp.UnlockBits(dstData);
            return bmp;
        }
Esempio n. 52
0
        // Blurs image; this has been written quickly and without reference;
        // should be modified in order to use a true gaussian kernel;
        // is left as is because shortly all convolution-like functions
        // will be handled by a single method (possibly with OpenCL)
        public static FloatMap FastBlurMap(FloatMap imgfIn)
        {
            int h = imgfIn.H;
            int w = imgfIn.W;
            int stride = imgfIn.Stride;

            var imgfOut = new FloatMap(w, h);

            const float k1 = 0.1715728f; // w = 2
            const float k2 = 0.0857864f; // w = 1
            const float k3 = 0.0606601f; // w = 1/1.4 = 0.7

            int lineStart = stride;
            for (int y = 1; y < h - 1; ++y)
            {
                int i = lineStart + 1; ;
                for (int x = 1; x < w - 1; ++x)
                {
                    imgfOut[i] = (imgfIn[i]) * k1 +
                                    (imgfIn[i + stride] + imgfIn[i - stride] + imgfIn[i+1] + imgfIn[i-1]) * k2 +
                                    (imgfIn[i + stride + 1] + imgfIn[i + stride - 1] + imgfIn[i - stride + 1] + imgfIn[i - stride - 1]) * k3;
                    ++i;
                }
                lineStart += stride;
            }
            return imgfOut;
        }
Esempio n. 53
0
 static FloatMap capHoles(FloatMap imgfIn, int filterHalfSize, out bool thereAreStillHoles)
 {
     return convolute(imgfIn, getDistanceWeightMap(filterHalfSize), out thereAreStillHoles);
 }
Esempio n. 54
0
 public static FloatMap GaussianBlur(FloatMap imgfIn, float sigma)
 {
     FloatMap blurMask = createBlurMask(sigma);
     bool dummy;
     return convolute(imgfIn, blurMask, out dummy);
 }
Esempio n. 55
0
        // http://www.thebigblob.com/gaussian-blur-using-opencl-and-the-built-in-images-textures/
        // http://haishibai.blogspot.it/2009/09/image-processing-c-tutorial-4-gaussian.html
        static FloatMap createBlurMask(float sigma)
        {
            int maskSize = (int)Math.Ceiling(3.0f * sigma);
            int _2maskSizePlus1 = (maskSize << 1) + 1; // stupid C# compiler gives precedence to sum
            FloatMap mask = new FloatMap(_2maskSizePlus1, _2maskSizePlus1);
            float sum = 0.0f;
            float temp = 0.0f;
            float _2sigmaSqrInvNeg = -1 / (sigma * sigma * 2);

            for (int a = -maskSize; a <= maskSize; ++a)
            {
                for (int b = -maskSize; b <= maskSize; ++b)
                {
                    temp = (float)Math.Exp(((float)(a * a + b * b) * _2sigmaSqrInvNeg));
                    sum += temp;
                    mask[a + maskSize + (b + maskSize) * _2maskSizePlus1] = temp;
                }
            }

            // Normalize the mask
            int _2maskSizePlus1Sqr = _2maskSizePlus1 * _2maskSizePlus1;
            for (int i = 0; i < _2maskSizePlus1Sqr; ++i)
            {
                mask[i] = mask[i] / sum;
            }

            return mask;
        }
Esempio n. 56
0
        public FloatMap ResizeMap(FloatMap inMap, int dstW, int dstH)
        {
            float xk = (float)inMap.W / (float)dstW;
            float yk = (float)inMap.H / (float)dstH;

            FloatMap outMap = new FloatMap(dstW, dstH);

            var k = _kernels["upsizeImg"];

            err = Cl.SetKernelArg(k, 2, floatSize, xk);
            assert(err, "xk setKernelArg");

            err = Cl.SetKernelArg(k, 3, floatSize, yk);
            assert(err, "yk setKernelArg");

            singlePass(k, inMap, outMap);

            return outMap;
        }
Esempio n. 57
0
        // Resizes map to arbitrary size
        private static FloatMap ResizeMap(FloatMap imgfIn, int dstW, int dstH)
        {
            int srcH = imgfIn.H;
            int srcW = imgfIn.W;
            int stride = imgfIn.Stride;

            float xk = srcW / dstW;
            float yk = srcH / dstH;

            FloatMap imgOut = new FloatMap(dstW, dstH);
            float dy = 0;
            int lineStart = 0;
            for (int y = 0; y < dstH; ++y)
            {
                float dx = 0;
                int i = lineStart;
                for (int x = 0; x < dstW; ++x)
                {
                    imgOut[i] = imgfIn[dx, dy];
                    dx += xk;
                    ++i;
                }
                lineStart += stride;
                dy += yk;
            }

            return imgOut;
        }
Esempio n. 58
0
 // Caps holes taking values (weighted by distance) from neighborhood
 // for interpolation; filter can cap holes as large as filterHalfSize*2;
 // multiple passes could be needed.
 public FloatMap CapHoles(FloatMap imgfIn, int filterHalfSize)
 {
     var mask = getDistanceWeightMap(filterHalfSize);
     bool thereAreStillHoles = true;
     while (thereAreStillHoles)
     {
         imgfIn = convolvec(imgfIn, mask, out thereAreStillHoles);
     }
     return imgfIn;
 }
Esempio n. 59
0
        FloatMap getMaxMap()
        {
            int h = _imgfs[0].H;
            int w = _imgfs[0].W;

            FloatMap imgfOut = new FloatMap(w, h);

            for (int y =0; y<h; ++y)
            {
                for (int x = 0; x < w; ++x )
                {
                    float v = getMaxIdx(x, y);
                    imgfOut[x, y] = v;// < 0 ? -1 : 255 - v * 255 / _imgfs.Count; // MOVED into map2BmpDepth
                }
            }

            return imgfOut;
        }
Esempio n. 60
0
        private FloatMap capHoles(FloatMap inMap, int filterHalfSize)
        {
            var k = _kernels["capHolesImg"];
            FloatMap outMap = new FloatMap(inMap.W, inMap.H);

            FloatMap mask = getDistanceWeightMap(filterHalfSize);

            IMem<float> maskBuf = Cl.CreateBuffer<float>(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, mask._buf, out err);
            assert(err, "capholes mask, mem object creation");

            err = Cl.SetKernelArg(k, 2, intPtrSize, maskBuf);
            assert(err, "capholes mask, setKernelArg");

            err = Cl.SetKernelArg(k, 3, intSize, filterHalfSize);
            assert(err, "capholes mask, setKernelArg");

            singlePass(k, inMap, outMap);

            Cl.ReleaseMemObject(maskBuf);

            return outMap;
        }