C++拉伸均衡的图像

C++ Stretching an equalized image

本文关键字:图像 C++      更新时间:2023-10-16

从一个(2)均衡的图像中,我必须创建一个(3)。

  1. 原始图像:https://i.stack.imgur.com/Lqzbv.jpg
  2. 均衡图像:https://i.stack.imgur.com/obhbT.png
  3. 均衡和拉伸图像:https://i.stack.imgur.com/V4aPR.png

有了OpenCV,我本可以使用equalizeHist()同时进行均衡和拉伸。

因此,如果不使用OPENCV,我如何从均衡图像中进行拉伸。均衡部分如下。

#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv/highgui.h>
#include <cstring>
using std::cout;
using std::cin;
using std::endl;
using namespace cv;
void imhist(Mat image, int histogram[])
{
    // initialize all intensity values to 0
    for (int i = 0; i < 256; i++)
    {
        histogram[i] = 0;
    }
    // calculate the no of pixels for each intensity values
    for (int y = 0; y < image.rows; y++)
        for (int x = 0; x < image.cols; x++)
            histogram[(int)image.at<uchar>(y, x)]++;
}
void cumhist(int histogram[], int cumhistogram[])
{
    cumhistogram[0] = histogram[0];
    for (int i = 1; i < 256; i++)
    {
        cumhistogram[i] = histogram[i] + cumhistogram[i - 1];
    }
}
int main()
{
    // Load the image
    Mat image = imread("y1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    // Generate the histogram
    int histogram[256];
    imhist(image, histogram);

    // Caluculate the size of image
    int size = image.rows * image.cols;
    float alpha = 255.0 / size;
    // Calculate the probability of each intensity
    float PrRk[256];
    for (int i = 0; i < 256; i++)
    {
        PrRk[i] = (double)histogram[i] / size;
    }
    // Generate cumulative frequency histogram
    int cumhistogram[256];
    cumhist(histogram, cumhistogram);
    // Scale the histogram
    int Sk[256];
    for (int i = 0; i < 256; i++)
    {
        Sk[i] = cvRound((double)cumhistogram[i] * alpha);
    }
    // Generate the equlized image
    Mat new_image = image.clone();
    for (int y = 0; y < image.rows; y++)
        for (int x = 0; x < image.cols; x++)
            new_image.at<uchar>(y, x) = saturate_cast<uchar>(Sk[image.at<uchar>(y, x)]);
    //////////////////////////////////////////
    // // Generate the histogram stretched image
    Mat str_image = new_image.clone();
    //for (int a = 0; a < str_image.rows; a++)
    //  for (int b = 0; b < str_image.cols; b++)
    // Display the original Image
    namedWindow("Original Image");
    imshow("Original Image", image);
    // Display equilized image
    namedWindow("Equalized Image");
    imshow("Equalized Image", new_image);

    waitKey();
    return 0;
}

通常的方法是找到最暗和最亮的像素。你可以在一个单一的循环中对所有像素进行迭代,伪代码如下:

darkest=pixel[0,0]   // assume first pixel is darkest for now, and overwrite later
brightest=pixel[0,0] // assume first pixel is lightest for now, and overwrite later
for all pixels
    if this pixel < darkest
       darkest = this pixel
    else if this pixel > brightest
       brightest = this pixel
    endif
end for

很简单。假设最暗和最亮的分别是80和220。现在,您需要将这个范围80..220扩展到整个范围0..255。

因此,你从图像中的每个像素中减去80,在直方图的左端向下移动到零,所以你的范围现在是0..140。所以现在你需要将每个像素乘以255/140,将右端拉伸到255。当然,您可以在像素阵列上一次性完成这两项运算。

for all pixels
   newvalue = int((current value - darkest)*255/(brightest-darkest))
end for