Opencv 直方图操作

让直方图的平均值m_0=128,标准差s_0=52吧!

这里并不是变更直方图的动态范围,而是让直方图变得平坦。

可以使用下式将平均值为m标准差为s的直方图变成平均值为m_0标准差为s_0的直方图:
x_{out}=\frac{s_0}{s}\ (x_{in}-m)+m_0

python实现:

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


# histogram manipulation
def hist_mani(img, m0=128, s0=52):
    m = np.mean(img)
    s = np.std(img)

    out = img.copy()

    # normalize
    out = s0 / s * (out - m) + m0
    out[out < 0] = 0
    out[out > 255] = 255
    out = out.astype(np.uint8)

    return out


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

out = hist_mani(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 transform
cv::Mat histogram_transform(cv::Mat img, int m0, int s0){
  // get height and width
  int width = img.cols;
  int height = img.rows;
  int channel = img.channels();

  // histogram transformation hyper-parameters
  double m, s;
  double sum = 0., squared_sum = 0.;
  double val;

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

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

  // get standard deviation
  m = sum / (height * width * channel);
  s = sqrt(squared_sum / (height * width * channel) - m * m);


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

        out.at<cv::Vec3b>(y, x)[c] = (uchar)(s0 / s * (val - m) + m0);
      }
    }
  }

  return out;
}


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

  // histogram transform
  cv::Mat out = histogram_transform(img, 128, 52);

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

  return 0;
}

输入:

Opencv 直方图操作

输出:

Opencv 直方图操作

直方图:

Opencv 直方图操作

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程