如何在opengl或webgl中使用CLAHE实现对比度限制自适应直方图均衡?

时间:2016-07-13 08:42:16

标签: javascript image-processing textures webgl

我正在尝试理解并在我的灰度和彩色图像上应用CLAHE。我还在第478页找到this book,这有助于用一些C ++代码和this tutorial解释CLAHE。

我对GLSL很新,无法用它来解决问题。任何人都可以帮我在OpenGL / WebGL中做到这一点吗?另外,我不允许使用OpenCV库。

修改 This link更全面。

偶数this是自适应直方图的另一个完美解决方案,但我需要通过更改直方图的能力来获得图像。

编辑2: 不知怎的,我能够让CLAHE在canvas 2d上工作,显然使用CPU,指的是这可以让任何人知道如何在GPU中做同样的事情?

这是fiddle

代码: `

var iml = document.getElementById('imageLoader');
iml.addEventListener('change', handleImage, false);

var cnv = document.getElementById('imageCanvas');
var ctx = cnv.getContext('2d');
var cnvori = document.getElementById('imageOriginalCanvas')
var ctxori = cnvori.getContext('2d');

function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
        var img = new Image;

        img.onload = function(){

            cnvori.width = cnv.width = img.width;
            cnvori.height = cnv.height = img.height;
            ctx.drawImage(img,0,0,img.width,img.height);
            ctxori.drawImage(img,0,0,img.width,img.height);

            var imgData = ctx.getImageData(0,0,img.width,img.height);


            var min=255, max=0;
            var intens=[];
            var levels=[];
            var j=0;

            for (var i=0;i<imgData.data.length;i+=4) {
                intens[j] = (imgData.data[i]+imgData.data[i+1]+imgData.data[i+2] )/3;
                j++;
            }

            var tilesize = [32, 32];
            var clipLimit = 0.1;

            // number of bins
            var num_bins = 256;

            var h = img.height;

            var w = img.width;
            // number of tiles in x and y direction
            var xtiles = Math.ceil(w / tilesize[0]);
            var ytiles = Math.ceil(h / tilesize[1]);

            var cdfs = new Array(ytiles);
            for(var i=0;i<ytiles;i++)
                cdfs[i] = new Array(xtiles);

            var inv_tile_size = [1.0 / tilesize[0], 1.0 / tilesize[1]];

            var cdf = [];
            // create histograms
            for(var i=0;i<ytiles;i++){
                var y0 = i * tilesize[1];
                var y1 = y0 + tilesize[1];
                for(var j=0;j<xtiles;j++)
                {
                    var x0 = j * tilesize[0];
                    var x1 = x0 + tilesize[0];
                    var hist = histogram(intens, x0, y0, x1, y1, num_bins, h, w);

                    cdfs[i][j] = buildcdf(hist, num_bins, tilesize[0] * tilesize[1], clipLimit);
                }
            }

            var finalArray = [];
            var p = 0;
            for(var y=0, idx=0;y<h;++y){
                for(var x=0;x<w;++x, idx+=4){
                    // intensity of current pixel
                    var I = Math.floor(intens[y*w+x]);

                    var tx = x * inv_tile_size[0] - 0.5;
                    var ty = y * inv_tile_size[1] - 0.5;

                    var xl = Math.max(Math.floor(tx), 0);
                    var xr = Math.min(xl+1, xtiles-1);

                    var yt = Math.max(Math.floor(ty), 0);
                    var yd = Math.min(yt+1, ytiles-1);

                    var fx = tx - xl;
                    var fy = ty - yt;

                    var cdf11 = (cdfs[yt][xl][I]) * 255 ;
                    var cdf12 = (cdfs[yd][xl][I]) * 255;
                    var cdf21 = (cdfs[yt][xr][I]) * 255;
                    var cdf22 = (cdfs[yd][xr][I]) * 255;

                    var Iout = (1 - fx) * (1 - fy) * cdf11
                        + (1 - fx) *       fy  * cdf12
                        +      fx  * (1 - fy) * cdf21
                        +      fx  *      fy  * cdf22;

                    finalArray[p] = Iout;
                    p++;
                }
            }   
            var pixelLength = h * w;

            for (var index = 0, indexToFill = 3; index < pixelLength; index++, indexToFill = indexToFill + 4) {
                var result = finalArray[index];
                imgData.data[indexToFill-3] = 0;
                imgData.data[indexToFill-2] = 0;
                imgData.data[indexToFill-1] = 0;
                imgData.data[indexToFill] = 255 - result;
            }

            ctx.putImageData(imgData,0,0);
        }
        img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]); 
}

var getInputArray = function(mArray, x, y, hDiff, vDiff, rows, columns){
        var inputArray = [];
        var k = 0;
        for(var i=x-vDiff;i<=x+vDiff;i++){
            for(var j=y-hDiff;j<=y+hDiff;j++){
                if(i>=0 && j>=0 && i<rows && j<columns){
                    inputArray[k] = mArray[i][j];
                }else{
                    inputArray[k] = 0;
                }
                k++;
            }
        }
        var finalResult = getHEArray(inputArray, x, y, mArray);
        return finalResult;
    }

    // build cdf from given pdf
    function buildcdf(hist, num_bins, num_pixels, clipLimit){
        var excess = 0;
        for(var i=0;i<num_bins;++i){
            hist[i] = hist[i] / num_pixels;
            if(hist[i]>clipLimit){
                excess = excess + hist[i] - clipLimit;
                hist[i] = clipLimit;
            }
        }
        var addExcess = excess/num_bins;
        var cumuhist = [];
        cumuhist[0] = hist[0] + addExcess;
        for(var i=1;i<num_bins;++i)
            cumuhist[i] = cumuhist[i-1] + hist[i] + addExcess;

        return cumuhist;
    }

    function histogram(intens, x1, y1, x2, y2, num_bins, h, w){
        var hist = [];
        for(var i=0;i<num_bins;++i)
            hist[i] = 0;

        for(var y=y1;y<y2;++y){
            for(var x=x1;x<x2;++x){
                var idx;
                if(x>=w && y<h){
                    idx = (y * w + (w - 1));
                }else if(y>=h && x<w){
                    idx = ((h-1) * w + x);
                }else if(y>=h && x>=w){
                    idx = (h * w) - 1;
                }else{
                    idx = (y * w + x);
                }
                var val = Math.floor(intens[idx]);
                hist[val]++;
            }
        }
        return hist;
    }

`

0 个答案:

没有答案