计算出的直方图看起来不像预期的那样

时间:2015-07-19 11:51:03

标签: javascript image-processing html5-canvas typescript

我正在尝试实现直方图RGB但我的算法不像图形程序那样产生类似的表面。例如,此网站上的图片:

OpenCV histogram

我的版本如下:

RGB Histogram R channel

正如我所理解的那样,RGB直方图只是测量每个值在特定通道中出现的频率。所以我以这样的方式实现它:

        public Process(layerManager: dl.LayerManager) {
            var surface = layerManager.GetCurrent();
            var components = new Uint8Array(1024);
            surface.ForEachPixel((arr: number[], i: number): void => {
                components[arr[i]] += 1;
                components[arr[i + 1] + 256] += 1;
                components[arr[i + 2] + 512] += 1;
                components[arr[i + 3] + 768] += 1;
            });
            var histogram = layerManager.GetHistogram();
            histogram.Clear();
            var viewPort = layerManager.GetHistogramViewPort();
            viewPort.Clear();
            this.DrawColor(histogram, components, 0, new ut.Color(255, 0, 0, 255));
            //histogram.SetBlendMode(ds.BlendMode.Overlay);
            //this.DrawColor(histogram, components, 256, new ut.Color(0, 255, 0, 255));
            //this.DrawColor(histogram, components, 512, new ut.Color(0, 0, 255, 255));
        }

        private DrawColor(surface: ds.ICanvas, components: Uint8Array, i: number, fillStyle: ut.Color) {
            var point = new ut.Point(0, 255);
            surface.BeginPath();
            surface.FillStyle(fillStyle.R, fillStyle.G, fillStyle.B, fillStyle.A);
            surface.RGBAStrokeStyle(fillStyle.R, fillStyle.G, fillStyle.B, fillStyle.A); 
            surface.LineWidth(1);
            surface.MoveTo(point);
            for (var j = i + 256; i < j; ++i) {
                point = new ut.Point(point.X + 1, 255 - components[i]);
                surface.ContinueLine(point);
            }
            surface.ClosePathAndStroke();

            var viewPort = layerManager.GetHistogramViewPort();
            viewPort.DrawImage(surface.Self<HTMLElement>(), 0, 0, 255, 255, 0, 0, viewPort.Width(), viewPort.Height()); 
        }

我错过了什么吗?

1 个答案:

答案 0 :(得分:2)

您有一个Uint8Array数组来保存结果,但最常见的RGB值发生的次数超过255次。这会导致溢出,并且您最终会看到以256为模的值的直方图,这对于高值实际上是随机的。这就是为什么图的左边和中间部分(值小于255)是正确的,但是更高价值的区域到处都是。

使用较大的数据类型来存储结果,并在绘制之前将其标准化为输出画布的大小。