# Histogram

Histogram bir görseldeki piksel yogunluklarını gösteren grafiktir. Tek scale üzerinden yapılır yani ya ayrı ayrı r,g,b değerler üzerinden ya da gray dönüşümüyle bakılabilir. 0-255 arası yatay düzlemde hangi renkten ne kadar oldugunu dikeyde gösterir. Bu görselin renk dağılımı ve kontrast ve parlaklık değerleri ile ilgili bize fikir verir. Bazen bu değerler 'bin'lerle ifade edilir meselsa 0-255lik kısım 16'lık binlere bölünür ve o şekilde bir grafik oluşturulur.

[OpenCV Linki](https://docs.opencv.org/4.x/d1/db7/tutorial_py_histogram_begins.html)

```python
  pth:str = r"C:\Users\asus\rag0nn\EngReader\test_data\2.JPG"
  src = cv.imread(cv.samples.findFile(pth))
  if src is None:
      print('Could not open or find the image')
      exit(0)
  
  bgr_planes = cv.split(src)
  
  histSize = 256
  
  histRange = (0, 256) # the upper boundary is exclusive
  
  accumulate = False
  
  b_hist = cv.calcHist(bgr_planes, [0], None, [histSize], histRange, accumulate=accumulate)
  g_hist = cv.calcHist(bgr_planes, [1], None, [histSize], histRange, accumulate=accumulate)
  r_hist = cv.calcHist(bgr_planes, [2], None, [histSize], histRange, accumulate=accumulate)
  
  hist_w = 512
  hist_h = 400
  bin_w = int(round( hist_w/histSize ))
  
  histImage = np.zeros((hist_h, hist_w, 3), dtype=np.uint8)
  
  # bir pikseldeki yoğunluk çok yüksek olursa grafik taşabilir ya da kötü gönürür o yüzden 400'e kadar normalize ediyoruz.
  cv.normalize(b_hist, b_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)
  cv.normalize(g_hist, g_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)
  cv.normalize(r_hist, r_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)
  
  for i in range(1, histSize):
      cv.line(histImage, ( bin_w*(i-1), hist_h - int(b_hist[i-1]) ),
              ( bin_w*(i), hist_h - int(b_hist[i]) ),
              ( 255, 0, 0), thickness=2)
      cv.line(histImage, ( bin_w*(i-1), hist_h - int(g_hist[i-1]) ),
              ( bin_w*(i), hist_h - int(g_hist[i]) ),
              ( 0, 255, 0), thickness=2)
      cv.line(histImage, ( bin_w*(i-1), hist_h - int(r_hist[i-1]) ),
              ( bin_w*(i), hist_h - int(r_hist[i]) ),
              ( 0, 0, 255), thickness=2)
  
  cv.imshow('Source image', src)
  cv.imshow('calcHist Demo', histImage)
  cv.waitKey()
```

```python
  import numpy as np
  import cv2 as cv
  from matplotlib import pyplot as plt
  
  img = cv.imread('home.jpg')
  assert img is not None, "file could not be read, check with os.path.exists()"
  color = ('b','g','r')
  for i,col in enumerate(color):
      histr = cv.calcHist([img],[i],None,[256],[0,256])
      plt.plot(histr,color = col)
      plt.xlim([0,256])
  plt.show()
  ```

# Histogram Eşitleme
Görseldeki değerleri daha çarpıcı ve dengeli haline getirme amacıyla görseldeki piksellerle biraz oynayarak bilgi açısından daha net görseller elde etmeye yarar. Direkt opencv üzerinden yapılabilir.

![Histogram-Output](https://media.geeksforgeeks.org/wp-content/uploads/20250811213944522610/Histogram-output.webp)

```python
  import cv2
  
  img = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)
  
  equalized = cv2.equalizeHist(img)
  
  cv2.imshow("Original", img)
  cv2.imshow("Histogram Equalized", equalized)
  cv2.waitKey(0)
  cv2.destroyAllWindows()
  
  
```

# CLAHE ( Contrast Limited Adaptive Histogram Equalization)

Tüm görselde histograma bakmak yerine alt dilimlerde histogram eşitleme yapar sornasında bir bileear interpolating yöntemiyle aralardaki renk farklılıkalrını giderir.

Fonsksiyonda tilesize dilim boyutunu gösterir ve genelde 8,8 kullanılır. cl ise clip limitin üstüne çıkan bin'lerin kesilmesini eşikleyen değerdir.

![Equalization](https://docs.opencv.org/4.x/equalization_opencv.jpg)

```python
  import cv2
  
  img = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)
  
  cl = 2.0  # clipLimit
  tile_size = (8, 8)
  
  clahe = cv2.createCLAHE(clipLimit=cl, tileGridSize=tile_size)
  cl1 = clahe.apply(img)
  
  cv2.imshow("Original", img)
  cv2.imshow("CLAHE", cl1)
  cv2.waitKey(0)
  cv2.destroyAllWindows()
  
```