Problem: Gaussian Weighted Image Processing Computations

The problem requires developing C++ functions for image processing tasks: generating random images/matrices, applying Gaussian spatial weighting or adaptive corrections, computing weighted statistics (mean, variance, correlation) and enhanced contrast metrics, and returning specified results to support image analysis applications.


Input/Output: The problem receives integer parameters M, N for functions problem_5_1 and problem_5_5; integers M, N, T for problem_5_2; integers M, N and a double sigma for problem_5_3; integers M, N and doubles gain, offset for problem_5_4; integers M, N and a double contrast_factor for problem_5_6. It also accepts test parameters including specific values for these parameters and expected correct results. The problem generates return values: a double for problem_5_1, 5_3–5_6 and an int for problem_5_2, computed via generating random data (images/matrices), applying operations like Gaussian-weighted averaging, filtering, adaptive correction, correlation, or contrast enhancement. It also produces test results ("Correct"/"Wrong") for each case (using tolerance for doubles) and a "Completely correct!" message if all pass. Each function’s inputs drive its computation, and test inputs validate outputs against expected values.

Required dependencies:
#include <vector>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;

Sub-steps:
step_number: 1
step_description_prompt: Please use C++ to write a function named problem_5_1 that takes two integers M and N as parameters and returns a double. The function generates an M×N random image (each pixel value is 0-255) and computes the Gaussian-weighted normalized mean of the image pixels normalized to [0,1]. The function definition is double problem_5_1(int M, int N);. The algorithm steps are: 1. Create a 2D vector<vector<int>> image with M rows and N columns, each element set to rand() % 256. 2. Calculate center_i = M / 2.0, center_j = N / 2.0, and sigma = min(M, N) / 4.0. 3. Initialize sum = 0.0 and weight_sum = 0.0. Iterate over each pixel (i,j) in image: compute dist_sq = (i - center_i)*(i - center_i) + (j - center_j)*(j - center_j), weight = exp(-dist_sq / (2.0 * sigma * sigma)), add (image[i][j]/255.0)*weight to sum and weight to weight_sum. 4. Return weight_sum > 1e-10 ? sum / weight_sum : 0.0. Assume functions like rand(), exp(), min() are already defined.
function_header: double problem_5_1(int M, int N)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 5.1" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int M1 = 600;
    int N1 = 600;
    double result1 = problem_5_1(M1, N1);    double correct1 = 0.500839;  // Expected value (updated from actual result)
    if (abs(result1 - correct1) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 2
    int M2 = 512;
    int N2 = 512;
    double result2 = problem_5_1(M2, N2);    double correct2 = 0.499941;  // Expected value (updated from actual result)
    if (abs(result2 - correct2) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 3
    int M3 = 1024;
    int N3 = 768;
    double result3 = problem_5_1(M3, N3);    double correct3 = 0.499504;  // Expected value (updated from actual result)
    if (abs(result3 - correct3) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 2
step_description_prompt: Please write a C++ function named problem_5_2 that takes three integers M, N, T as parameters and returns an integer. The function signature is int problem_5_2(int M, int N, int T);. First, create a 2D vector<int> image of size M rows and N columns, where each element is a random integer between 0 and 255 generated by rand() % 256. Then, compute a weighted count: set center_i = M / 2.0, center_j = N / 2.0, sigma = min(M, N) / 4.0. Iterate over each element (i,j) in the image; if image[i][j] > T, calculate dist_sq as the squared Euclidean distance from (i,j) to (center_i, center_j), compute weight as 1.0 + 0.5 * exp(-dist_sq / (2.0 * sigma * sigma)), and accumulate these weights into a double variable weighted_count initialized to 0.0. Finally, return (int)(weighted_count + 0.5). Assume necessary headers (e.g., <vector>, <cstdlib>, <cmath>) are included.
function_header: int problem_5_2(int M, int N, int T)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 5.2" << endl;
    
    int correct_count = 0;
    
    // Test 1
    int M1 = 600;
    int N1 = 600;
    int T1 = 128;
    int result1 = problem_5_2(M1, N1, T1);    int correct1 = 210662;  // Expected value (updated from actual result)
    if (result1 == correct1) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 2
    int M2 = 600;
    int N2 = 600;
    int T2 = 64;
    int result2 = problem_5_2(M2, N2, T2);    int correct2 = 316726;  // Expected value (updated from actual result)
    if (result2 == correct2) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 3
    int M3 = 600;
    int N3 = 600;
    int T3 = 200;
    int result3 = problem_5_2(M3, N3, T3);    int correct3 = 90938;  // Expected value (updated from actual result)
    if (result3 == correct3) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 3
step_description_prompt: Write a C++ function double problem_5_3(int M, int N, double sigma) that generates a random M×N image with pixel values in [0,255], applies Gaussian filtering, computes weighted means of the original and filtered images using Gaussian spatial weighting based on distance to the image center, and returns the difference between the weighted original mean and weighted filtered mean. The function is defined as: double problem_5_3(int M, int N, double sigma);. Algorithm flow: 1. Create an M×N vector of integers (image) where each element is rand()%256; compute original_sum as the sum of all image elements, then original_mean = original_sum/(M*N). 2. Define a Gaussian kernel function as exp(-(x*x + y*y)/(2*sig*sig))/(2*3.14159265358979323846*sig*sig). 3. Calculate kernel_size as (int)(6*sigma)+1; if kernel_size is even, increment by 1. Compute half = kernel_size/2. 4. Create a kernel_size×kernel_size vector of doubles (kernel); for each (i,j) in kernel, set kernel[i][j] to the Gaussian function value with x=i-half, y=j-half, sig=sigma; compute sum_kernel as the sum of all kernel elements, then normalize kernel by dividing each element by sum_kernel. 5. Initialize an M×N vector of doubles (filtered) to 0.0. For each (i,j) in image, compute filtered[i][j] as the sum over all (ki,kj) in kernel of (image[ni][nj] * kernel[ki][kj]) where ni = i+ki-half, nj = j+kj-half, and ni is in [0,M-1] and nj is in [0,N-1] (ignore out-of-bounds pixels). 6. Compute center_i = M/2.0, center_j = N/2.0, sigma_weight = max(M,N)/4.0. For each (i,j) in image, compute dist_sq = (i-center_i)*(i-center_i) + (j-center_j)*(j-center_j), weight = exp(-dist_sq/(2*sigma_weight*sigma_weight)). Calculate filtered_sum += filtered[i][j]*weight and weight_sum += weight; compute filtered_mean = (weight_sum>1e-10) ? (filtered_sum/weight_sum) : 0.0. 7. Calculate weighted_original_sum and weight_sum_orig by repeating step 6 with image instead of filtered. Compute weighted_original_mean = (weight_sum_orig>1e-10) ? (weighted_original_sum/weight_sum_orig) : 0.0. 8. Return weighted_original_mean - filtered_mean. Assume all used functions (e.g., rand(), exp()) are already defined.
function_header: double problem_5_3(int M, int N, double sigma)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 5.3" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int M1 = 600;
    int N1 = 600;
    double sigma1 = 1.0;
    double result1 = problem_5_3(M1, N1, sigma1);    double correct1 = 0.070168;  // Expected value (updated from actual result)
    if (abs(result1 - correct1) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 2
    int M2 = 600;
    int N2 = 600;
    double sigma2 = 2.0;
    double result2 = problem_5_3(M2, N2, sigma2);    double correct2 = 0.149204;  // Expected value (updated from actual result)
    if (abs(result2 - correct2) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 3
    int M3 = 600;
    int N3 = 600;
    double sigma3 = 3.0;
    double result3 = problem_5_3(M3, N3, sigma3);    double correct3 = 0.236330;  // Expected value (updated from actual result)
    if (abs(result3 - correct3) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 4
step_description_prompt: Please write a C++ function named problem_5_4 that takes four parameters (int M, int N, double gain, double offset) and returns a double. This function generates a DN matrix, calculates mean DN, applies a non-linear radiation correction with adaptive quadratic model, and returns the average reflectance.

Function definition: double problem_5_4(int M, int N, double gain, double offset);

Algorithm steps: 1. Create a 2D vector DN of size M×N with int elements initialized to 0. 2. Fill each DN[i][j] with rand()%1001 (range 0-1000), compute the sum of all DN elements (dn_sum). 3. Calculate mean_dn as dn_sum/(M*N). 4. Compute reflectance_sum: iterate over each DN[i][j], normalize DN to dn_norm (DN[i][j]/1000.0), calculate adaptive_gain (gain*(1.0 + 0.1*(DN[i][j]-mean_dn)/1000.0)) and adaptive_offset (offset*(1.0 + 0.05*(DN[i][j]-mean_dn)/1000.0)), compute reflectance as adaptive_gain*dn_norm*dn_norm*1000.0 + adaptive_offset*DN[i][j] + 0.001*DN[i][j], add to reflectance_sum. 5. Return reflectance_sum/(M*N).

Other functions (like rand(), vector) are assumed to be defined.
function_header: double problem_5_4(int M, int N, double gain, double offset)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 5.4" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int M1 = 600;
    int N1 = 600;
    double gain1 = 0.01;
    double offset1 = 0.05;
    double result1 = problem_5_4(M1, N1, gain1, offset1);    double correct1 = 28.939338;  // Expected value (updated from actual result)
    if (abs(result1 - correct1) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 2
    int M2 = 600;
    int N2 = 600;
    double gain2 = 0.02;
    double offset2 = 0.1;
    double result2 = problem_5_4(M2, N2, gain2, offset2);    double correct2 = 57.385673;  // Expected value (updated from actual result)
    if (abs(result2 - correct2) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 3
    int M3 = 600;
    int N3 = 600;
    double gain3 = 0.015;
    double offset3 = 0.05;
    double result3 = problem_5_4(M3, N3, gain3, offset3);    double correct3 = 30.638532;  // Expected value (updated from actual result)
    if (abs(result3 - correct3) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 5
step_description_prompt: Please write a C++ function named problem_5_5 that computes the weighted Pearson correlation coefficient between two randomly generated M×N matrices using Gaussian spatial weighting.
The function definition is double problem_5_5(int M, int N).
Algorithm flow:1. Create two M×N vectors of vectors band1 and band2 (type double).2. Fill band1 and band2 with random values from 0 to 1 using (double)rand() / RAND_MAX.3. Compute center_i = M / 2.0, center_j = N / 2.0, sigma = min(M, N) / 4.0.4. Calculate weighted_sum1, weighted_sum2, and weight_sum by iterating over each element (i,j): compute dist_sq = (i - center_i)^2 + (j - center_j)^2, weight = exp(-dist_sq / (2.0 * sigma * sigma)), then accumulate weighted_sum1 += band1[i][j] * weight, weighted_sum2 += band2[i][j] * weight, weight_sum += weight.5. Compute mean1 = (weight_sum > 1e-10) ? (weighted_sum1 / weight_sum) : 0.0, mean2 = (weight_sum > 1e-10) ? (weighted_sum2 / weight_sum) : 0.0.6. Calculate numerator, denom1, denom2 by re-iterating each element (i,j): recompute the same weight, diff1 = band1[i][j] - mean1, diff2 = band2[i][j] - mean2, accumulate numerator += weight * diff1 * diff2, denom1 += weight * diff1 * diff1, denom2 += weight * diff2 * diff2.7. Compute denominator = sqrt(denom1 * denom2), return (denominator < 1e-10) ? 0.0 : (numerator / denominator).
Assume functions like rand(), RAND_MAX, exp(), sqrt(), and min() are already available. Use vector<vector<double>> for matrices.
function_header: double problem_5_5(int M, int N)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 5.5" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int M1 = 600;
    int N1 = 600;
    double result1 = problem_5_5(M1, N1);    double correct1 = -0.000415;  // Expected value (updated from actual result)
    if (abs(result1 - correct1) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 2
    int M2 = 512;
    int N2 = 512;
    double result2 = problem_5_5(M2, N2);    double correct2 = 0.001382;  // Expected value (updated from actual result)
    if (abs(result2 - correct2) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 3
    int M3 = 1024;
    int N3 = 768;
    double result3 = problem_5_5(M3, N3);    double correct3 = 0.000420;  // Expected value (updated from actual result)
    if (abs(result3 - correct3) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

step_number: 6
step_description_prompt: Please write a C++ function named problem_5_6 that takes three parameters (int M, int N, double contrast_factor) and returns a double, which represents the ratio of the standard deviation of the contrast-enhanced image to the original image's standard deviation. The function implements adaptive contrast enhancement with spatial Gaussian weighting and local window adjustment.

Function definition: double problem_5_6(int M, int N, double contrast_factor);

Algorithm steps:
1. Generate an M×N image where each pixel is a random integer between 0 and 255 using rand() % 256.
2. Calculate the weighted mean of the image using spatial Gaussian weighting:
   - Compute center_i = M / 2.0, center_j = N / 2.0, sigma_mean = min(M, N) / 4.0.
   - For each pixel (i,j), calculate weight as exp(-((i-center_i)² + (j-center_j)²)/(2*sigma_mean²)), then compute weighted_sum (sum of pixel*weight) and weight_sum (sum of weights).
   - Mean is weighted_sum / weight_sum (use 0 if weight_sum ≤ 1e-10).
3. Calculate the original weighted variance and standard deviation:
   - Variance is sum of weight*(pixel - mean)² divided by weight_sum (use 1 if weight_sum ≤ 1e-10).
   - Std_dev_orig is the square root of variance.
4. Perform adaptive contrast enhancement and compute enhanced image statistics:
   - Use a local window of size 5 (half_window = 2) to compute local mean for each pixel (sum valid neighboring pixels in the window and divide by count).
   - For each pixel:
     - Compute global_enhanced = (pixel - mean)*contrast_factor + mean.
     - Compute local_enhanced = (pixel - local_mean)*contrast_factor*1.2 + local_mean.
     - Blend enhanced = 0.6*global_enhanced + 0.4*local_enhanced, then clamp to [0.0, 255.0].
   - Calculate the weighted variance of the enhanced image using the same Gaussian weights as step 2:
     - Compute variance_enhanced as sum of weight*(enhanced_pixel - mean)² divided by weight_sum_enhanced (sum of weights for enhanced image).
     - Std_dev_enhanced is the square root of variance_enhanced.
5. Return std_dev_enhanced / std_dev_orig.

Note: Assume functions like rand(), exp(), sqrt(), max(), min() are already defined. The random image generation uses rand() % 256 for each pixel. The local window size is fixed at 5, with half_window = window_size / 2. The enhanced pixel value is clamped to 0-255. The Gaussian weight for variance calculation (both original and enhanced) uses the same sigma_mean as the weighted mean. The adaptive enhancement blends global (0.6 weight) and local (0.4 weight) enhanced values, with the local enhancement using a 1.2x contrast factor multiplier.
function_header: double problem_5_6(int M, int N, double contrast_factor)
test_cases: // ==================== Main function: Testing ====================
int main() {
    srand(42);
    cout << fixed << setprecision(6);
    cout << "Problem 5.6" << endl;
    
    int correct_count = 0;
    const double tolerance = 1e-5;
    
    // Test 1
    int M1 = 600;
    int N1 = 600;
    double contrast_factor1 = 1.5;
    double result1 = problem_5_6(M1, N1, contrast_factor1);    double correct1 = 1.321034;  // Expected value (updated from actual result)
    if (abs(result1 - correct1) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 2
    int M2 = 600;
    int N2 = 600;
    double contrast_factor2 = 2.0;
    double result2 = problem_5_6(M2, N2, contrast_factor2);    double correct2 = 1.431660;  // Expected value (updated from actual result)
    if (abs(result2 - correct2) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    // Test 3
    int M3 = 600;
    int N3 = 600;
    double contrast_factor3 = 2.5;
    double result3 = problem_5_6(M3, N3, contrast_factor3);    double correct3 = 1.494707;  // Expected value (updated from actual result)
    if (abs(result3 - correct3) < tolerance) {
        cout << "Correct" << endl;
        correct_count++;
    } else {
        cout << "Wrong" << endl;
    }
    
    if (correct_count == 3) {
        cout << "Completely correct!" << endl;
    }
    
    return 0;
}

General solution:

General tests: