I want to create a raster dataset by calculating the average value of every pixel, for 14 images. The images are 10980 * 10980, and they are 14 in total.
The main program is:
//Main program
int main()
{
char path[100];
char suffix[100];
printf("Enter path to list files: ");
scanf("%s", path);
printf("Enter the wildcard: ");
scanf("%s", suffix);
struct Node *B02;
B02 = NULL;
struct Node *SCL;
SCL = NULL;
B02 = recurList(path, suffix);
printf("Printing B02_head!\n");
show(B02);
char *suffix_scl = "SCL_10m.tif";
SCL = recurListSCL(path, suffix_scl);
printf("Printing files in SCL head:\n");
show(SCL);
int B02_length = 0;
int SCL_length = 0;
B02_length = getCount(B02);
SCL_length = getCount(SCL);
printf("BO2 of length: %d\n", B02_length);
printf("SCL of length: %d\n", SCL_length);
struct Node* p;
p = B02 ->next;
struct Node *s;
s = SCL ->next;
int counter = 1;
int n_imgs;
n_imgs = B02_length;
float *l[n_imgs];
float *scl_l[n_imgs];
char *out = "B02_avg.tif";
int nX;
int nY;
GDALAllRegister();
GDALDatasetH hD[n_imgs];
GDALDatasetH slcD[n_imgs];
GDALDriverH hDr[n_imgs];
GDALDriverH sclDr[n_imgs];
GDALRasterBandH hB[n_imgs];
GDALRasterBandH sclB[n_imgs];
for(int i=0; i<n_imgs;i++){
printf("%s\n", B02->data);
hD[i] = GDALOpen(B02->data, GA_ReadOnly);
slcD[i] = GDALOpen(SCL->data, GA_ReadOnly);
hDr[i] = GDALGetDatasetDriver(hD[i]);
sclDr[i] = GDALGetDatasetDriver(slcD[i]);
hB[i] = GDALGetRasterBand(hD[i],1);
sclB[i] = GDALGetRasterBand(slcD[i],1);
int nX = GDALGetRasterBandXSize(hB[0]);
l[i] = (float *) malloc(sizeof(float)*nX);
scl_l[i] = (float *) malloc(sizeof(float)*nX);
B02=B02->next;
SCL=SCL->next;
}
nX =GDALGetRasterBandXSize(hB[1]);
nY = GDALGetRasterBandYSize(hB[0]);
//int N = nX*nY;
// Creating output file
//hD[n_imgs] = GDALCreateCopy(hDr[0], out, hD[0],FALSE,NULL,NULL,NULL);
//hB[n_imgs] = GDALGetRasterBand(hD[n_imgs],1);
//l[n_imgs] = (float *) malloc(sizeof(float)*nX);
//scl_l[n_imgs] = (float *) malloc(sizeof(float)*nX);
//Accessing the data rowxrow
printf("Checking the value of keeper.\n");
printf("%s\n", B02->data);
printf("pointer\n");
printf("%s\n", p->data);
int nrows = n_imgs;
int ncols = nX;
int (*arr)[ncols] = malloc(sizeof(int[nrows][ncols]));
int (*arr_scl)[ncols] = malloc(sizeof(int[nrows][ncols]));
if(arr == NULL || arr_scl == NULL) {
printf("malloc failed to allocate memory\n");
}
for(int row=0;row<1;row++){
float *out_line;
out_line= (float *) malloc(sizeof(float)*nX);
float *mask_count;
mask_count = (float*) malloc(sizeof(float)*nX);
float *avg_line;
avg_line = (float *) malloc(sizeof(float)*nX);
int n_null_pix;
n_null_pix = 0;
for (int i = 0;i<n_imgs;i++){
GDALDatasetH scl_raster;
GDALDatasetH raster;
GDALAllRegister();
raster = GDALOpen( p->data, GA_ReadOnly);
scl_raster = GDALOpen( s->data, GA_ReadOnly);
GDALRasterBandH raster_band;
GDALRasterBandH scl_band;
raster_band = GDALGetRasterBand(raster, 1);
scl_band = GDALGetRasterBand(scl_raster,1);
float *line;
float *line_scl;
int value;
int mask;
line = (float *) CPLMalloc(sizeof(float)*nX);
line_scl = (float*) CPLMalloc(sizeof(float)*nX);
GDALRasterIO(raster_band, GF_Read,0, row, nXSize,1, line, nXSize, 1, GDT_Float32, 0, 0);
GDALRasterIO(scl_band, GF_Read, 0, row, nXSize, 1, line_scl, nXSize, 1, GDT_Float32, 0, 0);
for(int col=0;col<nXSize; col++){
value = line[col];
mask = line_scl[col];
if(mask == 0 || mask ==1 || mask == 3 || mask == 8 || mask == 9
|| mask == 10 || mask == 11)
{
value = 0;
printf("val:%d::imgID:%d::COOR(<%d,%d>)\n", value, i, row,col);
out_line[col] += value;
mask_count[col] += 0;
printf("n_imgs:%d, col:%d\n", i, col);
arr[n_imgs][col] = value;
arr_scl[n_imgs][col] += 0;
}
else
{
printf("val:%d::imgID:%d::COOR(<%d,%d>)\n", value, i, row,col);
out_line[col] += value;
mask_count[col] += 1;
printf("n_imgs:%d, col:%d\n", i, col);
arr[n_imgs][col] = value;
arr_scl[n_imgs][col] += 1;
}
}
CPLFree(line);
CPLFree(line_scl);
p = p->next;
s = s->next;
}
for(int i = 0; i <n_imgs; i++){
for (int j = 0; j <nX; j++){
int value = arr[i][j];
int scl_value = arr_scl[i][j];
printf("row:%d,col:%d,val:%d,scl_value:%d\n",i,j, value, scl_value);
}
}
/*
int counter = 0;
for(int i = 0; i <nY; i++){
int num;
num = out_line[i];
int denom;
denom = mask_count[i];
int val;
val = out_line[i]/mask_count[i];
int mask_value = mask_count[i];
printf("%d/%d\n", num,denom);
printf("val:%d\n", val);
avg_line[i] = val;
counter ++;
}*/
//GDALRasterIO(hB[n_imgs], GF_Write,0,row,nX,1,avg_line,nX,1,GDT_Float32,0,0);
//CPLFree(out_line);
//CPLFree(avg_line);
//CPLFree(mask_count);
}
return 0;
}
Basically I am doing only a run of the program for the first row, then the program iterates over images, and reads the first row of every one of them, to afterwards, iterate over every cell (cols). It checks if the pixel is valid or invalid according to the value at this location for the scene classification layer (for Sentinel-2 imagery is the one created by the Sen2Cor, and for 10 m spatial resolution finishes with the suffix SCL_10m.tif.
The program seems to work well, but when I iterate over the values of the array 2D, created by inserting the values in the previous iteration, it prints something like:
ow:8,col:7687,val:21627268,scl_value:24641956
row:8,col:7688,val:20644165,scl_value:22020460
row:8,col:7689,val:21823802,scl_value:22479242
row:8,col:7690,val:24445275,scl_value:21234000
row:8,col:7691,val:26214788,scl_value:20775181
row:8,col:7692,val:29622700,scl_value:23331173
row:8,col:7693,val:25690522,scl_value:23134527
row:8,col:7694,val:23396720,scl_value:17301832
row:8,col:7695,val:25297263,scl_value:11534546
row:8,col:7696,val:23789927,scl_value:19988757
row:8,col:7697,val:23265646,scl_value:25756023
This values are for the iteration over the 2D array
for(int i = 0; i <n_imgs; i++){
for (int j = 0; j <nX; j++){
int value = arr[i][j];
int scl_value = arr_scl[i][j];
printf("row:%d,col:%d,val:%d,scl_value:%d\n",i,j, value, scl_value);
}
}
I don't know, it seems that when declaring the 2D array that will contain the values I get from the first row of every image, the initial value is garbage collected from whatever was at the memory at this location.
I don't know if my approach should use the calloc function instead of malloc in
int (*arr)[ncols] = malloc(sizeof(int[nrows][ncols]));
The rest of the code from which I am able to get the list of raster files by its extension is here:
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "gdal/gdal.h"
#include "gdal/cpl_conv.h"
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <sys/stat.h>
#include<stdio.h>
#include "gdal/gdal.h"
#include "gdal/cpl_conv.h"
int const nYSize = 10980, nXSize = 10980;
//Node Structure for Linked-List
struct Node
{
char *data;
struct Node *next;
};
//Declaring global variables
struct Node *B02_list = NULL;
struct Node *SCL_list = NULL;
// Function to replace a string with another
// string
char* str_replace(char* string, const char* substr, const char* replacement) {
char* tok = NULL;
char* newstr = NULL;
char* oldstr = NULL;
int oldstr_len = 0;
int substr_len = 0;
int replacement_len = 0;
newstr = strdup(string);
substr_len = strlen(substr);
replacement_len = strlen(replacement);
if (substr == NULL || replacement == NULL) {
return newstr;
}
while ((tok = strstr(newstr, substr))) {
oldstr = newstr;
oldstr_len = strlen(oldstr);
newstr = (char*)malloc(sizeof(char) * (oldstr_len - substr_len + replacement_len + 1));
if (newstr == NULL) {
free(oldstr);
return NULL;
}
memcpy(newstr, oldstr, tok - oldstr);
memcpy(newstr + (tok - oldstr), replacement, replacement_len);
memcpy(newstr + (tok - oldstr) + replacement_len, tok + substr_len, oldstr_len - substr_len - (tok - oldstr));
memset(newstr + oldstr_len - substr_len + replacement_len, 0, 1);
free(oldstr);
}
free(string);
return newstr;
}
//Function to insert a node into a Linked-List
struct Node *insert(struct Node *Head, char *value)
{
struct Node *new_string;
new_string = (struct Node *)malloc(sizeof(struct Node));
new_string->data = malloc(strlen(value)+1);
strcpy(new_string->data,value);
struct Node *temp;
temp = (struct Node*)malloc(sizeof(struct Node));
if (Head == NULL)
{
temp -> data = new_string->data;
Head = temp;
Head -> next = Head;
}
else
{
temp ->data = new_string->data;
temp ->next = Head ->next;
Head -> next = temp;
}
return Head;
}
//Function to check if a string finishes with a suffix
int string_ends_with(const char * str, const char * suffix)
{
int str_len = strlen(str);
int suffix_len = strlen(suffix);
return
(str_len >= suffix_len) &&
(0 == strcmp(str + (str_len-suffix_len), suffix));
}
//Function to show the elements of the Linked-List
void show(struct Node *Head)
{
struct Node *ptr;
if (Head == NULL)
{
printf("List is empty.!");
return;
}
ptr = Head ->next;
do
{
printf("%s\n", ptr->data);
ptr = ptr->next;
} while (ptr != Head->next);
}
//Function to find the files in a directory based on a wildcard
struct Node * recurList(char *basePath, char *suffix)
{
char path[1000];
struct dirent *dp;
DIR *dir = opendir(basePath);
while ((dp = readdir(dir)) != NULL)
{
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
{
strcpy(path, basePath);
strcat(path, "/");
strcat(path, dp->d_name);
struct stat s;
if (stat(path, &s) == 0)
{
if( s.st_mode & S_IFDIR )
{
recurList(path, suffix);
}
else if(s.st_mode &S_IFREG)
{
if (string_ends_with(path, suffix))
{
B02_list = insert(B02_list, path);
}
}
}
}
}
return B02_list;
closedir(dir);
}
//Function to find the SCL files in a directory
struct Node * recurListSCL(char *basePath, char *suffix)
{
char path[1000];
struct dirent *dp;
DIR *dir = opendir(basePath);
while ((dp = readdir(dir)) != NULL)
{
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
{
strcpy(path, basePath);
strcat(path, "/");
strcat(path, dp->d_name);
struct stat s;
if (stat(path, &s) == 0)
{
if( s.st_mode & S_IFDIR )
{
recurListSCL(path, suffix);
}
else if(s.st_mode &S_IFREG)
{
if (string_ends_with(path, suffix))
SCL_list = insert(SCL_list, path);
}
}
}
}
return SCL_list;
closedir(dir);
}
//Function that counts the number of nodes in a linked-list
int getCount(struct Node* head)
{
int count = 0;
struct Node* p;
p = head ->next;
do
{
printf("%s\n", p->data);
p = p->next;
count++;
} while (p != head->next);
return count;
}
Could anyone help me to clarify this point, Why I am not able to print out plausible values in my 2D array, and which kind of array allocation function (malloc or calloc) should I use?