Ask Your Question

Revision history [back]

Here is the C++ variant. However go through it and please take a look at all the comments I made. As you see, you are making it way to complex using the C-API.

// -------------------------------------------------------
// Added all includes and namespaces needed for this code
// Add it in correct place of your program
// -------------------------------------------------------
#include "opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;
// -------------------------------------------------------

int block=5;
int w1=80;
double w;
Mat src, dst;

Mat quw(Mat src, int block, double w)
{
    // ---------------------------------------------------
    // Useless variables
    // ---------------------------------------------------

    , 

    Mat j1 (src.cols, src.rows, CV_8UC1);
    Mat j2 (src.cols, src.rows, CV_8UC1);
    Mat j3 (src.cols, src.rows, CV_8UC1); 

    // This is quite weird, you define a global dst matrix but also a local one! Be aware of this
    // Also the destination is all of a sudden a 3 channel matrix, hope this is intended    
    ;
    // ---------------------------------------------------



    // Tried to order the variables in meaningfull groups
    // Copied them to the place they are actually used
    // Removed B G R channel variables and replaced them by vectors
    // Cleaned up the code    

    // Split the source in channels
    // You can now address them by index!
    vector<Mat> channels;
    split(src, channels);

    // Set a region of interest rect
    Rect ROI_rect ( Point(0,0), Size(block, block) );

    // Parameters needed after the looping also 
    Mat imgroi1 (block, block, CV_8UC1); 
    Mat imgroi2 (block, block, CV_8UC1);
    Mat imgroi3 (block, block, CV_8UC1);

    // Start your for loop, counters don't need to be initialized beforehand
    for(int i=0; i<src.cols/block; i++){
       for(int j=0; j<src.rows/block; j++){
       double min1, max1, min2, max2, min3, max3, min;

       // Copy of data to the destination matrices based on the ROI parameter
       // First grab the ROI of the channel, then copy it
           Mat roi1(channels[0], ROI_rect); roi1.copyTo(imgroi1);
           Mat roi2(channels[0], ROI_rect); roi2.copyTo(imgroi2);
           Mat roi3(channels[0], ROI_rect); roi3.copyTo(imgroi3);

       // Apply the min max localisation algorithm on each channel roi
           minMaxLoc(imgroi1, min1, max1);
       minMaxLoc(imgroi2, min2, max2);
       minMaxLoc(imgroi3, min3, max3);

       // Perform the if loops
           if(min1<min2){
        min=min1;
       }else{
        min=min2;
       }
       if(min>min3){
        min=min3;
       }
       // I think a piece of code was missing here, guessing you want a scalar
       // I created one, 4th element is not used since it is the alfa channel for opacity
       // But it seems it isn't used, remove it then
           Scalar minScalar(min,min,min);

       // Add the pixels to the dark channel
           Mat dark_channel = Mat::zeros(src.cols, src.rows, CV_8UC1);
       Mat roi_dark_channel = dark_channel(ROI_rect);
       // Then you are again doing some weird stuff which makes no sense
       // Is your goal here to color the min value that is returned into the dark_channel or so?
       // I will do that here --> setting all pixels of the mask into the lowest retrieved value, seems logical
       roi_dark_channel = min;

       // Adapt the ROI parameter
       ROI_rect.x = block*i;
           ROI_rect.y = block*j;        
       }
    }

    // Write away the image
    // It will contain at this point a matrix with for every block the minimal value
    imwrite("f:/dark_channel_prior.jpg", dark_channel);

    // Now some calculations on the dark_channel image are performed
    double min_dark, max_dark;
    Point min_loc, max_loc;          
    minMaxLoc(dark_channel, min_dark, max_dark, min_loc, max_loc);

    // Output the result and set the ROI with that
    cout<< max_loc.x << " " << max_loc.y << endl;
    ROI_rect.x=max_loc.x;
    ROI_rect.y=max_loc.y;

    // Lets perform some operations using the above data to create the output dst image      
    // Create the destination matrix, seperate channels, at the end combine them in the destination
    Mat dst1 (src.cols, src.rows, CV_8UC1); 
    Mat dst2 (src.cols, src.rows, CV_8UC1);
    Mat dst3 (src.cols, src.rows, CV_8UC1);

    // Set roi in the destination channels and copy info, then perform the minMaxLoc function again
    double A_dst1, dst1_min, A_dst2, dst2_min, A_dst3, dst3_min;      
    imgroi1.copyTo( dst1(ROI_rect) );   
    minMaxLoc(imgroi1, dst1_min, A_dst1);
    imgroi2.copyTo( dst2(ROI_rect) );   
    minMaxLoc(imgroi2, dst2_min, A_dst2);   
    imgroi3.copyTo( dst3(ROI_rect) );   
    minMaxLoc(imgroi13, dst3_min, A_dst3);

    cout << A_dst1 << " " << A_dst2 << " " << A_dst3 << endl;

    // Some new calculations
    // No idea here what the toushelv does exactly
    int m, n;
    Mat toushelv (src.cols, src.rows, CV_8UC1);

    for(int k=0; k<src.rows; k++){
       for(int l=0; l<src.cols; l++){
       m = dark_channel.at<uchar>(k,l);
           n = 255 - w*m;
       toushelv.at<uchar>(k,l) = n;
       }
    }

    imwrite("D:/toushelv.jpg",toushelv);  

    // Calculations for the haze
    double tx;
    double jj1,jj2,jj3;
    int ix,jx;

    Mat dst (src.cols, src.rows, CV_8UC3);

    for(int p=0; p<src.rows; p++){
       for(q=0; q<src.cols; q++){
      tx = toushelv.at<uchar>(p,q);
          tx = tx / 255.0;
          if (tx < 0.1){ tx = 0.1; }

      ix1 = channels[0].at<uchar>(p,q);
      ix2 = channels[1].at<uchar>(p,q);
      ix3 = channels[2].at<uchar>(p,q);
          jj1 = (ix1 - A_dst1) / (tx + A_dst1); 
          jj2 = (ix2 - A_dst2) / (tx + A_dst1);
          jj2 = (ix3 - A_dst3) / (tx + A_dst1);

      dst.at<uchar>(p,q) = Scalar(jj1,jj2,jj3);
       }
    }

    imwrite("D:/removed_haze.jpg",dst);
    return dst;
}

Here is the C++ variant. However go through it and please take a look at all the comments I made. As you see, you are making it way to complex using the C-API.

// -------------------------------------------------------
// Added all includes and namespaces needed for this code
// Add it in correct place of your program
// -------------------------------------------------------
#include "opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;
// -------------------------------------------------------

int block=5;
int w1=80;
double w;
Mat src, dst;

Mat quw(Mat src, int block, double w)
{
    // ---------------------------------------------------
    // Useless variables
    // ---------------------------------------------------

    , 

    Mat j1 (src.cols, src.rows, CV_8UC1);
    Mat j2 (src.cols, src.rows, CV_8UC1);
    Mat j3 (src.cols, src.rows, CV_8UC1); 

    // This is quite weird, you define a global dst matrix but also a local one! Be aware of this
    // Also the destination is all of a sudden a 3 channel matrix, hope this is intended    
    ;
    // ---------------------------------------------------



    // Tried to order the variables in meaningfull groups
    // Copied them to the place they are actually used
    // Removed B G R channel variables and replaced them by vectors
    // Cleaned up the code    

    // Split the source in channels
    // You can now address them by index!
    vector<Mat> channels;
    split(src, channels);

    // Set a region of interest rect
    Rect ROI_rect ( Point(0,0), Size(block, block) );

    // Parameters needed after the looping also 
    Mat imgroi1 (block, block, CV_8UC1); 
    Mat imgroi2 (block, block, CV_8UC1);
    Mat imgroi3 (block, block, CV_8UC1);

    // Start your for loop, counters don't need to be initialized beforehand
    for(int i=0; i<src.cols/block; i++){
       for(int j=0; j<src.rows/block; j++){
       double min1, max1, min2, max2, min3, max3, min;

       // Copy of data to the destination matrices based on the ROI parameter
       // First grab the ROI of the channel, then copy it
           Mat roi1(channels[0], ROI_rect); roi1.copyTo(imgroi1);
           Mat roi2(channels[0], ROI_rect); roi2.copyTo(imgroi2);
           Mat roi3(channels[0], ROI_rect); roi3.copyTo(imgroi3);

       // Apply the min max localisation algorithm on each channel roi
           minMaxLoc(imgroi1, min1, max1);
       minMaxLoc(imgroi2, min2, max2);
       minMaxLoc(imgroi3, min3, max3);

       // Perform the if loops
           if(min1<min2){
        min=min1;
       }else{
        min=min2;
       }
       if(min>min3){
        min=min3;
       }
       // I think a piece of code was missing here, guessing you want a scalar
       // I created one, 4th element is not used since it is the alfa channel for opacity
       // But it seems it isn't used, remove it then
           Scalar minScalar(min,min,min);

       // Add the pixels to the dark channel
           Mat dark_channel = Mat::zeros(src.cols, src.rows, CV_8UC1);
       Mat roi_dark_channel = dark_channel(ROI_rect);
       // Then you are again doing some weird stuff which makes no sense
       // Is your goal here to color the min value that is returned into the dark_channel or so?
       // I will do that here --> setting all pixels of the mask into the lowest retrieved value, seems logical
       roi_dark_channel = min;

       // Adapt the ROI parameter
       ROI_rect.x = block*i;
           ROI_rect.y = block*j;        
       }
    }

    // Write away the image
    // It will contain at this point a matrix with for every block the minimal value
    imwrite("f:/dark_channel_prior.jpg", dark_channel);

    // Now some calculations on the dark_channel image are performed
    double min_dark, max_dark;
    Point min_loc, max_loc;          
    minMaxLoc(dark_channel, min_dark, max_dark, min_loc, max_loc);

    // Output the result and set the ROI with that
    cout<< max_loc.x << " " << max_loc.y << endl;
    ROI_rect.x=max_loc.x;
    ROI_rect.y=max_loc.y;

    // Lets perform some operations using the above data to create the output dst image      
    // Create the destination matrix, seperate channels, at the end combine them in the destination
    Mat dst1 (src.cols, src.rows, CV_8UC1); 
    Mat dst2 (src.cols, src.rows, CV_8UC1);
    Mat dst3 (src.cols, src.rows, CV_8UC1);

    // Set roi in the destination channels and copy info, then perform the minMaxLoc function again
    double A_dst1, dst1_min, A_dst2, dst2_min, A_dst3, dst3_min;      
    imgroi1.copyTo( dst1(ROI_rect) );   
    minMaxLoc(imgroi1, dst1_min, A_dst1);
    imgroi2.copyTo( dst2(ROI_rect) );   
    minMaxLoc(imgroi2, dst2_min, A_dst2);   
    imgroi3.copyTo( dst3(ROI_rect) );   
    minMaxLoc(imgroi13, dst3_min, A_dst3);

    cout << A_dst1 << " " << A_dst2 << " " << A_dst3 << endl;

    // Some new calculations
    // No idea here what the toushelv does exactly
    int m, n;
    Mat toushelv (src.cols, src.rows, CV_8UC1);

    for(int k=0; k<src.rows; k++){
       for(int l=0; l<src.cols; l++){
       m = dark_channel.at<uchar>(k,l);
           n = 255 - w*m;
       toushelv.at<uchar>(k,l) = n;
       }
    }

    imwrite("D:/toushelv.jpg",toushelv);  

    // Calculations for the haze
    double tx;
    double jj1,jj2,jj3;
    int ix,jx;

    Mat dst (src.cols, src.rows, CV_8UC3);

    for(int p=0; p<src.rows; p++){
       for(q=0; q<src.cols; q++){
      tx = toushelv.at<uchar>(p,q);
          tx = tx / 255.0;
          if (tx < 0.1){ tx = 0.1; }

      ix1 = channels[0].at<uchar>(p,q);
      ix2 = channels[1].at<uchar>(p,q);
      ix3 = channels[2].at<uchar>(p,q);
          jj1 = (ix1 - A_dst1) / (tx + A_dst1); 
          jj2 = (ix2 - A_dst2) / (tx + A_dst1);
          jj2 = (ix3 - A_dst3) / (tx + A_dst1);

      dst.at<uchar>(p,q) = Scalar(jj1,jj2,jj3);
       }
    }

    imwrite("D:/removed_haze.jpg",dst);
    return dst;
}