Image processing-histogram equalization algorithm

Foreword:

Histogram equalization is an important application of gray scale transformation, which is efficient and easy to implement. It changes the grayscale of each pixel in the image by changing the histogram of the image, and is mainly used to enhance the contrast of the image with a small dynamic range. If an image is dark or light as a whole , the histogram equalization method is very suitable.

1. The histogram equalization function in OpenCV

Call the built-in function: cv2.equalizeHist
The input image of the histogram equalization algorithm in OpenCV needs to be an 8-bit single-channel image, which is a grayscale image. If you want to calculate the equalized image of the color image, you can first separate the image with the split function, process the image of each channel separately, and merge the image with the merge function.

import cv2
import numpy as np
img = cv2.imread('img.jpg', 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dat = cv2.equalizeHist(gray)
cv2.imshow('gray', gray)a
cv2.imshow('dat', dat)
cv2.waitKey(0)

Second, the algorithm steps

  1. Determine the gray level of the image;
  2. Calculate the distribution probability p(i) of the original histogram;
  3. Calculate the cumulative value of histogram probability s(i);
  4. Grayscale mapping

Three, python code:

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('img.jpg', 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
count = np.zeros(256, np.float)
for i in range(img.shape[0]):
    for j in range(img.shape[1]):
        count[int(gray[i, j])] += 1 # 统计该像素出现的次数
count = count / (img.shape[0] * img.shape[1]) # 得到概率
x = np.linspace(0,255,256)
plt.bar(x, count,color = 'b')
plt.show()

# 计算累计概率
for i in range(1,256):
    count[i] += count[i - 1]
# 映射
map1 = count * 255
for i in range(img.shape[0]):
    for j in range(img.shape[1]):
        p = gray[i, j]
        gray[i, j] = map1[p]
cv2.imshow('gray', gray)
cv2.waitKey(0)

Four, C++ code:

#include <opencv2\opencv.hpp>
#include <iostream>

using namespace cv;

int main()
{
    
    
    Mat srcImg,grayImg;//声明原始图和灰度度
    srcImg = imread("1.jpg");//载入原始图
    if(!srcImg.data)
    {
    
    
        std::cout<<"请确认路径下存在图片";
        return -1;
    }
    imshow("原始图",srcImg);//显示原始图
    cvtColor(srcImg,grayImg,CV_RGB2GRAY);//将rgb图像转化为灰度图
    int rowNumber = grayImg.rows;//得到行
    int colNumber = grayImg.cols;//得到列
    int sumNumber = rowNumber*colNumber;//得到图像整个像素个数
    Mat dstImg(rowNumber,colNumber,CV_8UC1,Scalar(0,0,0));//初始化直方图均衡化后的图
    double hist[256] = {
    
    0.00};//直方图
    double dhist[256] = {
    
    0.00};//直方图归一化图
    double Dhist[256] = {
    
    0.00};//直方图积分图,每一个像素点
    for(int i = 0;i<rowNumber;i++)//遍历原始图像,得到直方图
    {
    
    
        uchar* data = grayImg.ptr<uchar>(i);
        for(int j = 0;j<colNumber;j++)
        {
    
    
            int temp = data[j];//得到图像像素值
            hist[temp] = hist[temp]+1;//将相应像素值在直方图中加1
        }
    }

    for(int i = 0;i<256;i++)//遍历直方图,得到归一化直方图和积分图
    {
    
           
        dhist[i] = hist[i]/sumNumber;//得到归一化图
        for(int j = 0;j<=i;j++)
        {
    
    
            Dhist[i] = Dhist[i] + dhist[j]; //得到积分图
        }
    }


    for(int i = 0;i<rowNumber;i++)//以积分图为查找表得到均衡化后的图
    {
    
    
        uchar* data1 = dstImg.ptr<uchar>(i);
        uchar* data2 = grayImg.ptr<uchar>(i);
        for(int j = 0;j<colNumber;j++)
        {
    
    
            int temp1 = data2[j]; //查找到原始图相应位置的像素值
            int temp2 = (int)(Dhist[temp1]*255); //在积分图中找到相应像素值的映射值
            data1[j] = temp2;//将映射值赋值给目标图像相应值
        }
    }
    imshow("均衡化后的图",dstImg);
    waitKey(0);
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_42823043/article/details/109289294