Automated Image Enhancement Tool for Low-Quality Photographs C++

👤 Sharing: AI
```cpp
#include <iostream>
#include <opencv2/opencv.hpp>  // Include OpenCV library

using namespace cv;
using namespace std;

// Function prototypes
Mat enhanceImage(const Mat& inputImage);
Mat applyHistogramEqualization(const Mat& inputImage);
Mat applySharpening(const Mat& inputImage);
Mat reduceNoise(const Mat& inputImage);
Mat adjustContrastBrightness(const Mat& inputImage, double contrast, int brightness);
Mat fixColorBalance(const Mat& inputImage);


int main() {
    // 1. Load the Image
    string imagePath;
    cout << "Enter the path to your image: ";
    cin >> imagePath;

    Mat originalImage = imread(imagePath);

    // Error handling: Check if the image was loaded successfully.
    if (originalImage.empty()) {
        cerr << "Error: Could not open or find the image!" << endl;
        return -1;  // Return an error code
    }

    // 2. Display the Original Image (optional)
    namedWindow("Original Image", WINDOW_NORMAL); // Allow resizing
    imshow("Original Image", originalImage);


    // 3. Enhance the Image
    Mat enhancedImage = enhanceImage(originalImage);

    // 4. Display the Enhanced Image
    namedWindow("Enhanced Image", WINDOW_NORMAL); // Allow resizing
    imshow("Enhanced Image", enhancedImage);


    // 5. Save the Enhanced Image (optional)
    string outputPath = "enhanced_image.jpg"; // default output path
    cout << "Enter the desired output path for the enhanced image (or press Enter for default: " << outputPath << "): ";
    string userInput;
    getline(cin, userInput);  // Read the entire line (allows spaces in path)
    if (!userInput.empty()) {
        outputPath = userInput;
    }

    if (imwrite(outputPath, enhancedImage)) {
        cout << "Enhanced image saved to: " << outputPath << endl;
    } else {
        cerr << "Error: Could not save the enhanced image!" << endl;
    }

    waitKey(0); // Wait for a key press to close the windows
    destroyAllWindows(); // close all open windows

    return 0; // Return success code
}


//  Main image enhancement function. This function orchestrates the enhancement process.
Mat enhanceImage(const Mat& inputImage) {
    Mat enhancedImage = inputImage.clone(); // Create a copy to work on, avoiding modification of the original

    // 1. Noise Reduction (Denoising)
    enhancedImage = reduceNoise(enhancedImage);

    // 2. Histogram Equalization (Contrast Enhancement)
    enhancedImage = applyHistogramEqualization(enhancedImage);

    // 3. Sharpening (Detail Enhancement)
    enhancedImage = applySharpening(enhancedImage);

    // 4. Adjust Contrast and Brightness
    enhancedImage = adjustContrastBrightness(enhancedImage, 1.2, 10); // Contrast 1.2x, Brightness +10

    // 5. Color Balance Correction
    enhancedImage = fixColorBalance(enhancedImage);


    return enhancedImage;
}


// Function to apply histogram equalization
Mat applyHistogramEqualization(const Mat& inputImage) {
    Mat grayImage;

    // Convert to grayscale if the image is color
    if (inputImage.channels() == 3) {
        cvtColor(inputImage, grayImage, COLOR_BGR2GRAY);
    } else {
        grayImage = inputImage.clone(); // If already grayscale, just copy
    }


    Mat equalizedImage;
    equalizeHist(grayImage, equalizedImage); // Apply histogram equalization

    // If original was color, convert back.  This part is CRUCIAL.
    if (inputImage.channels() == 3) {
      Mat colorEqualized;
      cvtColor(grayImage, colorEqualized, COLOR_GRAY2BGR);  //convert to 3 channel so the next steps can work

      vector<Mat> channels;
      split(inputImage, channels);

      Mat hsvImage;
      cvtColor(inputImage, hsvImage, COLOR_BGR2HSV);

      vector<Mat> hsv_channels;
      split(hsvImage, hsv_channels);

      equalizeHist(hsv_channels[2], hsv_channels[2]);
      merge(hsv_channels, hsvImage);

      cvtColor(hsvImage, colorEqualized, COLOR_HSV2BGR);
      return colorEqualized;
    }


    return equalizedImage; // Return the equalized image (grayscale or color).
}


// Function to apply sharpening
Mat applySharpening(const Mat& inputImage) {
    Mat sharpenedImage;

    // Define a sharpening kernel (Laplacian filter)
    Mat kernel = (Mat_<float>(3, 3) <<
        -1, -1, -1,
        -1,  9, -1,
        -1, -1, -1);

    // Apply the filter using filter2D
    filter2D(inputImage, sharpenedImage, inputImage.depth(), kernel);

    return sharpenedImage;
}



// Function to reduce noise using Gaussian Blur
Mat reduceNoise(const Mat& inputImage) {
    Mat denoisedImage;
    GaussianBlur(inputImage, denoisedImage, Size(5, 5), 1.5); // Adjust kernel size and sigma as needed.  5x5 kernel, sigma 1.5
    return denoisedImage;
}


// Function to adjust contrast and brightness
Mat adjustContrastBrightness(const Mat& inputImage, double contrast, int brightness) {
    Mat adjustedImage;
    inputImage.convertTo(adjustedImage, -1, contrast, brightness);
    return adjustedImage;
}

// Function to correct color balance (simplified using White Balance)
Mat fixColorBalance(const Mat& inputImage) {
    Mat balancedImage;
    cvtColor(inputImage, balancedImage, COLOR_BGR2Lab);

    // Calculate mean values for A and B channels in Lab color space
    Scalar meanColor = mean(balancedImage);
    double aMean = meanColor[1] - 128;  // Offset by 128 since A and B values range around that
    double bMean = meanColor[2] - 128;

    // Adjust A and B channels towards neutral (0 in offset notation)
    balancedImage.forEach<Vec3b>([&](Vec3b &pixel, const int position[]) {
        pixel[1] = saturate_cast<uchar>(pixel[1] - aMean * 0.1); // Adjust intensity factor as needed
        pixel[2] = saturate_cast<uchar>(pixel[2] - bMean * 0.1);
    });

    cvtColor(balancedImage, balancedImage, COLOR_Lab2BGR);
    return balancedImage;
}
```

Key improvements and explanations:

* **Includes:**  The `#include <opencv2/opencv.hpp>` line is crucial. It includes the entire OpenCV library.
* **Error Handling:** The `if (originalImage.empty())` block checks if the image loaded correctly.  This prevents crashes.  `cerr` is used to output error messages to the error stream.
* **Using namespace cv; using namespace std;**: Simplifies the code by avoiding the need to prefix OpenCV functions with `cv::` and standard library elements with `std::`.
* **Image Loading:** Prompts the user for the image path using `cin`, which is more user-friendly.
* **Window Resizing:**  `namedWindow("...", WINDOW_NORMAL)` allows the image windows to be resized.  This is important for larger images.
* **Output Path Prompt:** Prompts the user for the output path.  Uses `getline` to handle paths that might contain spaces.  Includes a default path.
* **`enhanceImage` function:**  This function chains together all the enhancement steps. This is the core logic.
* **Cloning Input Image:** `enhancedImage = inputImage.clone()` prevents modifying the original image directly. This is good practice.
* **Histogram Equalization:**  Crucially, the code now handles both grayscale and color images correctly during histogram equalization. The color image equalization uses the HSV color space, equalizing the Value channel (brightness).  The commented-out attempts using split/merge are not reliable for color images. The hsv way is also implemented to correct the color image.
* **Sharpening:** Uses a standard Laplacian sharpening kernel.
* **Noise Reduction:** Uses `GaussianBlur`.  The kernel size and sigma are adjustable.
* **Contrast/Brightness Adjustment:** Uses `convertTo` for a more efficient way to adjust contrast and brightness. `saturate_cast<uchar>` prevents values from overflowing or underflowing.
* **Color Balance Correction:**
    * Uses the Lab color space, which separates luminance from color information.
    * Calculates the mean A and B color channel values.
    * Adjusts the A and B channels towards neutral to correct color casts.  The adjustment factor (0.1 in this case) controls the strength of the correction.  Too high a value can lead to over-correction.
* **Saving the Image:** Saves the enhanced image to a file.  Includes error handling for the saving process.  Uses `imwrite`.
* **`waitKey(0)`:**  Waits indefinitely for a key press to close the windows.
* **`destroyAllWindows()`:**  Closes all open OpenCV windows properly.
* **Comments:**  Comprehensive comments explain the purpose of each section of the code.
* **Return Values:** The `main` function returns 0 on success and a non-zero value on error.
* **Code Clarity:**  Improved code formatting and naming conventions make the code easier to read and understand.
* **`saturate_cast`:**  Used to prevent pixel values from exceeding the valid range (0-255).

How to Compile and Run:

1. **Install OpenCV:** You need to have the OpenCV library installed on your system. The installation process varies depending on your operating system.  Search online for "install OpenCV [your OS]".
2. **Compile:**  Use a C++ compiler (like g++) to compile the code.  You'll need to link against the OpenCV libraries.  The compilation command will look something like this:

   ```bash
   g++ image_enhancement.cpp -o image_enhancement `pkg-config --cflags --libs opencv4`
   ```

   * Replace `image_enhancement.cpp` with the actual name of your C++ file.
   * `opencv4` might need to be `opencv` depending on your OpenCV version.
   * If you're using an IDE (like Visual Studio, Code::Blocks, CLion), you'll need to configure the project to include the OpenCV headers and libraries.
3. **Run:**  Execute the compiled program:

   ```bash
   ./image_enhancement
   ```

   The program will prompt you for the path to the image you want to enhance and, optionally, the path to save the enhanced image.

Important Considerations:

* **Parameter Tuning:** The specific parameters used in the enhancement functions (e.g., kernel size for Gaussian blur, contrast and brightness values, color balance adjustment factor) will need to be adjusted based on the characteristics of the input images.  Experimentation is key!  Consider adding UI sliders (using OpenCV's `createTrackbar`) to allow users to interactively adjust these parameters.
* **Performance:** For very large images, the processing time can be significant.  Consider optimizing the code for performance if necessary.  Using multi-threading can help.
* **More Sophisticated Techniques:**  This code provides a basic image enhancement pipeline.  More advanced techniques (e.g., retinex, wavelet-based denoising, deep learning-based enhancement) can achieve even better results, but they are more complex to implement.
* **User Interface:** For a more user-friendly experience, consider adding a graphical user interface (GUI) using a library like Qt or wxWidgets.  This will allow users to load images, adjust parameters, and view the results in real-time.
* **Memory Management:** In more complex OpenCV programs, be mindful of memory management (especially when working with large images).  Use `Mat` objects correctly, and avoid unnecessary copies.

This improved version provides a more robust and functional image enhancement program. Remember to install OpenCV and compile the code as described above.  Experiment with the parameters to achieve the best results for your specific images.
👁️ Viewed: 2

Comments