1D array to 16bits greyscale mat

hello everyone.

That make a long time now that im blocked
and i didn’t find solutions yet. I really need your help.

I have a 1d dynamical int array which represent a grayscale image of 8288x5644 pixels. I try to display it using imshow. But the result is not good. I have a matrix of good dimension but with columns of 0 every 2 columns (ex: column 1, 0 , column 2, 0 column 3, o etc…).

I really dont understand why. Here my code and the link at the end is the data file.

main

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include "Fit.h"

using namespace cv;

int main(){

const char* path = "c:/.../light_m51_60.0s_bin1_l_gain60_20210515-015357_-9.4c_0001.fit";
    img Img;
    Fit::open(path, &Img);


float* newImg = new float[Img.totalPixels]; // just for rescale the dynamics of the image
    for (int i = 0; i < Img.totalPixels; i++) {
        newImg[i] = (Img.data[i] - 1000.0) / (9000 - 1000);
        if (newImg[i] < 0)
            newImg[i] = 0;
        if (newImg[i] > 1)
            newImg[i] = 1;
        Img.data[i] = (int)(65355* newImg[i]);

    }
    Mat m(Img.size[1], Img.size[0], CV_16U, Img.data);
    imshow("yolo", m);

}

Fit.h

#include "cfitsio/fitsio.h"
#include "GlobalStruct.h"



using namespace std;
class Fit
{
	
public:

    static void open(const char* path, img* Img);

	

private:
	static int getTotalPixel(int dim, long * size);
};

Fit.cpp

#include "fit.h"


void Fit::open(const char* path, img * Img) {

    int status = 0;
    int nullval = 0;
    int anynul = 0;
    fitsfile* fptr;
    fits_open_file(&fptr, path, READONLY, &status); // open file
    fits_get_img_dim(fptr, &Img->dim, &status);	// get dim of image (color or gray scale basicly
    Img->size = new long[Img->dim];
    fits_get_img_size(fptr, 2, Img->size, &status); // get size of image (pixels)
    Img->totalPixels = getTotalPixel(Img->dim, Img->size);
    Img->data = new int[Img->totalPixels];
    fits_read_img(fptr, ULONG_IMG, 1, Img->totalPixels, &nullval, Img->data, &anynul, &status);
    fits_close_file(fptr, &status);

}



int Fit::getTotalPixel(int dim, long* size) {
    int multOfAllPixel = 1;
    for (int i = 0; i < dim; i++)
        multOfAllPixel *= size[i];
    return multOfAllPixel;

}


GlobalStruct.h

#ifndef GLOBALSTRUCT_H
#define GLOBALSTRUCT_H


//Any type definitions needed
using namespace std;
typedef struct img
{
   
    long * size;
    long totalPixels;
    int dim;
    int *data;

} img;

#endif

the link to the file:

https://www.transfernow.net/dl/202106170bmYcJF3

thank you in advance!

Img.data is of type float but by saying CV_16U you claim it to be of unsigned short (uint16_t).

you decide what it should be, but be consistent.

you multiplied by 65355 which is probably a typo of 65535.

I would recommend sticking with float, which is CV_32F. floats need to be in the range of 0 … 1.

type problem here, your img struct has an int data pointer
(4 bytes per pixel, not 2, that’s why every second CV_16U pixel is 00)

it should be either:

Mat m(Img.size[1], Img.size[0], CV_32S, Img.data);

(and the range be adjusted)

or ushort *data in the Img struct

Thank you berak and crackwitz. You helped me a lot. Indeed if i use ushort than int, that solve my problem.