计算出的直方图看起来不像预期的那样
calculated histogram doesn't look as expected
我正在尝试实现直方图 RGB,但我的算法无法生成与图形程序中看起来相似的表面。例如本网站上的图片:
我的版本是这样的:
正如我所理解的那样,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());
}
我是不是漏掉了什么?
您有一个 Uint8Array
数组来保存结果,但最常见的 RGB 值出现了 255 次以上。这会导致溢出,您最终会看到以 256 为模的值的直方图,这对于高值来说实际上是随机的。这就是为什么图表的左侧和中间部分(值小于 255)是正确的,但较高值的区域到处都是。
使用更大的数据类型来存储结果,并在绘制之前标准化为输出的大小canvas。
我正在尝试实现直方图 RGB,但我的算法无法生成与图形程序中看起来相似的表面。例如本网站上的图片:
我的版本是这样的:
正如我所理解的那样,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());
}
我是不是漏掉了什么?
您有一个 Uint8Array
数组来保存结果,但最常见的 RGB 值出现了 255 次以上。这会导致溢出,您最终会看到以 256 为模的值的直方图,这对于高值来说实际上是随机的。这就是为什么图表的左侧和中间部分(值小于 255)是正确的,但较高值的区域到处都是。
使用更大的数据类型来存储结果,并在绘制之前标准化为输出的大小canvas。