Torchvision cannot save a tensor on integer type - save

I try to use Torch to resize some images which I did successfully. The resized images have integer type and when I try to save them I get the error below:
RuntimeError: result type Float can't be cast to the desired output type Byte
I used the code below to resize and save images:
image_temp = torchvision.transforms.Resize([200,200], antialias = True)(image_temp)
torchvision.utils.save_image(image_temp , './test.png')
If I convert the tensor or the image to float type, I can save it without error. Does someone know what the problem with integer data type and saving it is?

Related

Is it possible to use INT8 input layer for tensorrt?

I want to have input layer as 8bit integer, to avoid int->float conversion on CPU:
ITensor* data = network->addInput(
m_InputBlobName.c_str(), nvinfer1::DataType::kINT8,
DimsCHW{static_cast<int>(m_InputC), static_cast<int>(m_InputH),
static_cast<int>(m_InputW)});
but it gives me this error message:
[E] [TRT] Parameter check failed at: ../builder/Network.cpp::addInput::466, condition: type != DataType::kINT8
Is it possible to make it work, or INT8 is only intended to be used for approximate calculations?
I found python api with addInput description:
add_input()
addInput(const char *name, DataType type, Dims dimensions)=0 -> ITensor *
Add an input tensor to the network.
The name of the input tensor is used to find the index into the buffer array for an engine built from the network.
Parameters:
name (*) – The name of the tensor.
type (*) – The type of the data held in the tensor.
dimensions (*) – The dimensions of the tensor.
Only DataType::kFLOAT, DataType::kHALF and DataType::kINT32 are valid input tensor types. The volume of the dimensions, including the maximum batch size, must be less than 2^30 elements.
Returns: The new tensor or None if there is an error.

How to extract SIFT features from an image with normalized float values between 0 and 1?

I am using cv2 to compute SIFT features. The values of gray image is between 0 and 1 (continuous float values). The problem is that I am getting the following error if I don't save the type as uint8:
error: /io/opencv_contrib/modules/xfeatures2d/src/sift.cpp:1121: error: (-5) image is empty or has incorrect depth (!=CV_8U) in function detectAndCompute
after saving as uint8:
kp,des=sift.detectAndCompute(img,None)
plt.imshow(cv2.drawKeypoints(img, kp, out_img.copy()))
plt.show()
I am getting a complete blank image. Could someone please suggest a solution?
I could solve the problem by just bringing the floats values into 255 range. By the following commands:
data = data / data.max() #normalizes data in range 0 - 255
data = 255 * data
img = data.astype(np.uint8)

OpenCV retrieving value from a mat into an integer

I want to create a 1-D array of exactly 100 values and at each index store the index of another array. If I am to use std::vector<int16_t> someVector, how do I ensure that someVector has only 100 values and maybe add the first value at location 48 like someVector[48] = 29322, and so on.
As an alternative I tried creating a 1-D mat of Mat someArray(1,100,CV_16UC1,Scalar(9999)). Now when I try to retrieve the value at index 48, by using int retrievedValue = someArray.row(0).col(48), it says cannot convert from Mat to int.
I realize I'm doing something crazy for something very simple, but please help.
When you initialize vector you can set its size:
std::vector<int16_t> someVector(100);
This way it will be created with as array of 100 elements. But don't forget that size of vector may be changed later.
As for Mat, operators like row() or col() give you sub-matrix of initial matrix. So the code you created will return you a 1x1 matrix, not a short. If you want to access an element in matrix it should be:
int retrievedValue = someArray.at<ushort>(0,48);

Max value of a Mat datatype variable

I am new to opencv, so please help me in solving this basic query. I am trying to find the max. value of a Mat variable. I tried to use the max_element and minMaxLoc, but end up facing errors, as the function keeps saying the datatype matched is wrong. I checked it over and over again, but am not successful. here is my code.
ABS_DST is the MAT variable
double *estimate,*min;
CvPoint *minLoc,*maxLoc;
Size s = abs_dst.size();
int rows = s.height;
int cols = s.width;
double imagearray[rows][cols] = abs_dst.data();
minMaxLoc(imagearray,min,estimate,minLoc,maxLoc);
I even tried giving the Mat variable abs_dst directly. But have not succeeded. there's an optional input mask array, which I have ignored as I do not require that.
Do next:
Point[] Mat_To_Point = Your_Mat_Variable.toArray();
And next you can to sort your array
I think I got the answer. Thanks for your efforts. The problem is minMaxLoc doesn't take RGB images array, as it is 3 channel. I had to convert the ABS_DST to Gray scale.
Secondly,
it is not
CvPoint *minLoc,maxLoc;
it is
Point *minLoc,*maxLoc;
I need not convert it to array, as converting to Gray Scale will directly give me a 1D channel, enough for the minMaxLoc. My apologies for my own mistakes and thanks once again for your efforts.

Fourier transformation in frequency domain with opencv

I'm trying to implement the fourier transformation in frequency domain.
I used getOptimalDFTSize accordingly, and I copied the image and mask, in bigger images, suitable for fourier transformation. I used the sample code from here as a reference.
Now, I have to separate the real and imaginary part, and to perform pixelwise multiplication of the image imaginary part with the mask imaginary part, and the same for the real part.But when I try to do so, I get the following error message:
OpenCV Error: Assertion failed (type == srcB.type() && srcA.size() == srcB.size()) in mulSpectrums, file /build/buildd/opencv-2.1.0/src/cxcore/cxdxt.cpp, line 1855
/build/buildd/opencv-2.1.0/src/cxcore/cxdxt.cpp:1855: error: (-215) type == srcB.type() && srcA.size() == srcB.size() in function mulSpectrums
The code is following:
//fourier transfromation of real and imaginary part
Mat complex_image, real_image, complex_mask, real_mask;
cv::dft(new_image, complex_image, DFT_COMPLEX_OUTPUT);
cv::dft(new_image, real_image, DFT_REAL_OUTPUT);
cv::dft(new_mask, complex_mask, DFT_COMPLEX_OUTPUT);
cv::dft(new_mask, real_mask, DFT_REAL_OUTPUT);
//pixelwise multiplication
Mat multiplied_complex, multiplied_real;
cv::mulSpectrums(complex_image, complex_mask, multiplied_complex, DFT_COMPLEX_OUTPUT );
cv::mulSpectrums(real_image, real_mask, multiplied_real, DFT_REAL_OUTPUT);
What am I doing wrong here?
Image and mask should have same size (width and height) and (most probably this is problem) type. So if it is different type you need to convert one of them so they have equal type.

Resources