Opencv 直方图均衡化

来让均匀化直方图吧!

Opencv 直方图均衡化是使直方图变得平坦的操作,是不需要计算上面的问题中的平均值、标准差等数据使直方图的值变得均衡的操作。

均衡化操作由以下式子定义。S是总的像素数;Z_{max}是像素点的最大取值(在这里是255);h(z)表示取值为z的累积分布函数:
Z’ = \frac{Z_{max}}{S} \ \sum\limits_{i=0}^z\ h(i)

python实现:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# histogram equalization
def hist_equal(img, z_max=255):
    H, W, C = img.shape
    S = H * W * C * 1.

    out = img.copy()

    sum_h = 0.

    for i in range(1, 255):
        ind = np.where(img == i)
        sum_h += len(img[ind])
        z_prime = z_max / S * sum_h
        out[ind] = z_prime

    out = out.astype(np.uint8)

    return out


# Read image
img = cv2.imread("imori.jpg").astype(np.float)

# histogram normalization
out = hist_equal(img)

# Display histogram
plt.hist(out.ravel(), bins=255, rwidth=0.8, range=(0, 255))
plt.savefig("out_his.png")
plt.show()

# Save result
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.imwrite("out.jpg", out)

c++实现:

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <math.h>



// histogram equalization
cv::Mat histogram_equalization(cv::Mat img){
  // get height and width
  int width = img.cols;
  int height = img.rows;
  int channel = img.channels();

  // output image
  cv::Mat out = cv::Mat::zeros(height, width, CV_8UC3);

  // histogram equalization hyper-parameters
  double Zmax = 255;
  double hist[255];
  double S = height * width * channel;
  int val;
  double hist_sum = 0;


  // histogram initialization
  for (int i = 0; i < 255; i++){
     hist[i] = 0;
  }

  // get histogram sum
  for (int y = 0; y < height; y++){
    for (int x = 0; x < width; x++){
      for (int c = 0; c < channel; c++){
        val = (int)img.at<cv::Vec3b>(y, x)[c];
        hist[val] ++;
      }
    }
  }

  // histogram equalization
  for (int y = 0; y < height; y++){
    for (int x = 0; x < width; x++){
      for (int c = 0; c < channel; c++){
        val = (int)img.at<cv::Vec3b>(y, x)[c];

        // get histogram sum <= current pixel value
        hist_sum = 0;
        for (int l = 0; l < val; l++){
          hist_sum += hist[l];
        }
        // assign equalized value
        out.at<cv::Vec3b>(y, x)[c] = (uchar)(Zmax / S * hist_sum);
      }
    }
  }

  return out;
}


int main(int argc, const char* argv[]){
  // read image
  cv::Mat img = cv::imread("imori.jpg", cv::IMREAD_COLOR);

  // histogram equalization
  cv::Mat out = histogram_equalization(img);

  //cv::imwrite("out.jpg", out);
  cv::imshow("answer", out);
  cv::waitKey(0);
  cv::destroyAllWindows();

  return 0;
}

输入:

Opencv 直方图均衡化

输出:

Opencv 直方图操作

直方图:

Opencv 直方图均衡化

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程