Getting Different Results from MATLAB

Hello. I am trying to implement a paper which enhances images with bad contrast. For a fast prototyping I used MATLAB and got some results. After that, I implemented it by using OpenCV and C++. If I solve the problems I face in here, I am also going to implement it by using OpenCV’s CUDA module. When I run OpenCV version, I see that results are quite different and looks odd. What are my possible mistakes?

This is the MATLAB version

MATLAB Code
    clc, clear, close all
    InputImage = imread('C:\Users\batuh\Desktop\Tez\Literatür Taraması\Image_Processing\18_12_2020\Implementasyon\2018_Image Enhancement Methods For Fundus Retina Images_Gerekli_Dosyalar\e_ophtha_EX\e_optha_EX\EX\E0010643\DS00008G.JPG');

    %Splitting green channel
    InputImageGreenChannel = InputImage(:,:,2);

    %Power law transform for alpha = 0.9
    InputImagePowerLaw = uint8(1 * (double(InputImageGreenChannel).^(0.9)));


    figure(1)
    subplot(1,2,1),imshow(InputImageGreenChannel);
    subplot(1,2,2),imshow(InputImagePowerLaw);

    %Adaptive histogram equalization
    InputImageHistEq = adapthisteq(InputImagePowerLaw);

    figure(2)
    subplot(1,2,1),imshow(InputImagePowerLaw);
    subplot(1,2,2),imshow(InputImageHistEq);

    %Normalizing
    upperLim =  max(max(InputImageHistEq));
    lowerLim =  min(min(InputImageHistEq));
    InputImageContrastStreched = uint8((255 * double(InputImageHistEq - lowerLim))/double(upperLim - lowerLim));

    figure(3)
    subplot(1,2,1),imshow(InputImageHistEq);
    subplot(1,2,2),imshow(InputImageContrastStreched);

    %Average filtering
    h = fspecial('average');
    InputImageAverage = imfilter(InputImageContrastStreched, h);


    figure(4)
    subplot(1,2,1),imshow(InputImageContrastStreched);
    subplot(1,2,2),imshow(InputImageAverage);

    %Image sharpening
    InputImageSharpened = imsharpen(InputImageAverage);

    figure(5)
    subplot(1,2,1),imshow(InputImageAverage);
    subplot(1,2,2),imshow(InputImageSharpened);

    %Log transform
    InputImageLog = 1 * log(1 + double(InputImageSharpened)/255);

    figure(6)
    subplot(1,2,1),imshow(InputImageSharpened);
    subplot(1,2,2),imshow(InputImageLog);


    figure(7)
    subplot(1,2,1),imshow(InputImageGreenChannel);
    subplot(1,2,2),imshow(InputImageLog);
MATLAB Results

!





This is the OpenCV C++ version

OpenCV Code
    #include <iostream>
    #include <opencv2/opencv.hpp>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/intensity_transform.hpp>
    #include <opencv2/imgproc.hpp>
    #include <string>
    #include <opencv2/photo.hpp>


    int main()
    {

    	std::string inputImagePath = "C:\\Users\\batuh\\Desktop\\VS_2017_Projects\\Sabri_2018\\x64\\Release\\DS00008G.jpg";

    	cv::Mat inputImage = cv::imread(inputImagePath);

    	//Check if input image was successfully read or not
    	if (inputImage.empty() == 1)
    	{
    		std::cout << "Couldn't read the image: " << inputImagePath << std::endl;




    		return EXIT_FAILURE;
    	}
    	else {

    		std::cout << "Input image was successfully read..." << std::endl;

    	}


    	//Split input image into R, G, B channels
    	cv::Mat inputImageChannels[3];
    	cv::split(inputImage, inputImageChannels);
    	cv::Mat inputImageR = inputImageChannels[2];
    	cv::Mat inputImageG = inputImageChannels[1];
    	cv::Mat inputImageB = inputImageChannels[0];



    	std::cout << inputImageG.at<float>(225, 445) << std::endl;
    	inputImageG.convertTo(inputImageG, CV_8U);
    	std::cout << static_cast<int>(inputImageG.at<uchar>(225, 445)) << std::endl;


    	//Power Law Transformation	
    	cv::Mat inputImagePowerLaw;
    	cv::intensity_transform::gammaCorrection(inputImageG, inputImagePowerLaw, 0.9);
    	cv::imshow("Input Image G Channel", inputImageG);
    	cv::imshow("Power Law Image", inputImagePowerLaw);
    	cv::waitKey(0);

    	/////////////////////////////////////////////////////////////////////////////////////

    	//Adaptive Histogram Equalization
    	cv::Mat inputImageHistEq;
    	cv::Ptr<cv::CLAHE> claheHistEq = cv::createCLAHE();
    	claheHistEq->apply(inputImagePowerLaw, inputImageHistEq);
    	cv::imshow("Power Law Image", inputImagePowerLaw);
    	cv::imshow("CLAHE Image", inputImageHistEq);
    	cv::waitKey(0);
    	
    	/////////////////////////////////////////////////////////////////////////////////////


    	//Image normalization
    	cv::Mat inputImageNormalized;
        cv::normalize(inputImageHistEq, inputImageNormalized, 0, 255, cv::NORM_MINMAX, -1, cv::noArray());

    	
    	cv::imshow("CLAHE Image", inputImageHistEq);
    	cv::imshow("Contrast Strecthed Image", inputImageNormalized);
    	cv::waitKey(0);
    	
    	/////////////////////////////////////////////////////////////////////////////////////

    	//Image filtering 1: Average

    	cv::Mat inputImageAverage;
    	cv::GaussianBlur(inputImageNormalized, inputImageAverage, cv::Size(3, 3), 0, 0);
    	cv::imshow("Contrast Strecthed Image", inputImageNormalized);
    	cv::imshow("Average Image", inputImageAverage);
    	cv::waitKey(0);
    	
    	/////////////////////////////////////////////////////////////////////////////////////

    	//Image filtering 2: Sharpening
    	cv::Mat inputImageSharpened;
    	cv::Mat sharpeningKernel = (cv::Mat_<double>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
    	cv::filter2D(inputImageAverage, inputImageSharpened, -1, sharpeningKernel);	
    	cv::imshow("Average Image", inputImageAverage);
    	cv::imshow("Sharpened Image", inputImageSharpened);
    	cv::waitKey(0);
    	
    	/////////////////////////////////////////////////////////////////////////////////////
    	//Log Transform
    	cv::Mat inputImageLog;
    	cv::intensity_transform::logTransform(inputImageSharpened, inputImageLog);
    	cv::imshow("Input Image", inputImageG);
    	cv::imshow("Enhanced Image", inputImageLog);
    	cv::waitKey(0);

    	return 0;
    }
OpenCV Results

openCVGreenChannel
openCVPowerLaw
openCVAdaptiveHisteq
openCVNormalized
openCVAverage
openCVSharpened
openCVLogTransform

Order of result images in each version,

  1. Green channel
  2. Power Law result
  3. Adaptive Hist eq result
  4. Normalized image result
  5. Average image result
  6. Sharpened image result
  7. Log Transform image result

so… your results diverge at the adaptive equalization step.

perhaps drill down into the functions you used there (matlab vs opencv) and find out how they operate.

both seem to be “CLAHE” but they probably differ in default arguments/settings. the opencv variant looks more aggressive.

that is assuming the pictures you provided are true representations of the code (no mixup in file names or variables that are imshown)

1 Like

It seems that, in MATLAB, ‘ClipLimit’ — Contrast enhancement limit was set to 0.01 by default and its range is in between [0, 1]. By using getClipLimit() I learned that in OpenCV, ‘ClipLimit’ was set to 40 by default. So after I used setClipLimit()and set it to 0.01 manually, results got better. I checked OpenCV CLAHE documentation but couldn’t find any information about the ClipLimit value range and default values. But I still have problems in Log Transform. I used two different ways to take Log Transform of image.

Log Transform code
	//Log Transform
	cv::Mat inputImageLog1, inputImageLog2;
	inputImageSharpened.convertTo(inputImageSharpened, CV_32F);
	inputImageSharpened.convertTo(inputImageLog1, CV_32F);
	inputImageSharpened.convertTo(inputImageLog2, CV_32F);

	cv::log(1 + (inputImageSharpened/255), inputImageLog1);
	cv::intensity_transform::logTransform(inputImageSharpened, inputImageLog2);

cv::imwrite("C:\\Users\\batuh\\Desktop\\VS_2017_Projects\\Sabri_2018\\Results\\openCVLogTransform1.png", inputImageLog1);
	cv::imwrite("C:\\Users\\batuh\\Desktop\\VS_2017_Projects\\Sabri_2018\\Results\\openCVLogTransform2.png", inputImageLog2);

And those are the results,

Log Transform results

cv::Mat inputImageLog1
openCVLogTransform1

cv::Mat inputImageLog2;
openCVLogTransform2