2015-07-19 134 views
0

我試圖實現直方圖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()); 
     } 

我是否錯過了什麼?

回答

2

您有一個Uint8Array數組來保存結果,但最常見的RGB值發生超過255次。這會導致溢出,並且最終會看到模256值的直方圖,對於高值,這是有效的隨機值。這就是爲什麼圖的左側和中間部分(其中值小於255)是正確的,但高價值區域遍佈整個地方。

使用較大的數據類型存儲結果,並在繪製之前將其規格化爲輸出畫布的大小。

+0

你完全正確! – Puchacz

相關問題