How to read values from a CV_16FC4 matrix - opencv

How to read values from a CV_16FC4 matrix?
For example, here how i read from a CV_32FC4:
{
// Create the matrix.
cv::Mat RGBA32F = cv::Mat(16, 16, CV_32FC4);
// Read first value.
const cv::Vec4f color = RGBA32F.at<cv::Vec4f>(0, 0);
}
For CV_16FC4 it would be like:
{
cv::Mat RGBA16F = cv::Mat(16, 16, CV_16FC4);
const /*DataType*/ color = RGBA16F.at</* DataType*/>(0, 0);
}
I don't know what to put for DataType. I am using OpenCV 4.6.0.
Thank you!

Related

EmguCV equivalent to Java mat.put(i, 0, mv)

I'm trying to convert a Java class to a C# one using EmguCV. It's for a class in Unsupervised Learning. The teacher made a program using OpenCV and Java. I have to convert it to C#.
The goal is to implement a simple Face Recognition algorithm.
The method I'm stuck at:
Mat sample = train.get(0).getData();
mean = Mat.zeros(/*6400*/sample.rows(), /*1*/sample.cols(), /*CvType.CV_64FC1*/sample.type());
// Calculating it by hand
train.forEach(person -> {
Mat data = person.getData();
for (int i = 0; i < mean.rows(); i++) {
double mv = mean.get(i, 0)[0]; // Gets the value of the cell in the first channel
double pv = data.get(i, 0)[0]; // Gets the value of the cell in the first channel
mv += pv;
mean.put(i, 0, mv); // *********** I'm stuck here ***********
}
});
So far, my C# equivalent is:
var sample = trainSet[0].Data;
mean = Mat.Zeros(sample.Rows, sample.Cols, sample.Depth, sample.NumberOfChannels);
foreach (var person in trainSet)
{
var data = person.Data;
for (int i = 0; i < mean.Rows; i++)
{
var meanValue = (double)mean.GetData().GetValue(i,0);
var personValue = (double)data.GetData().GetValue(i, 0);
meanValue += personValue;
}
}
And I am not finding the put equivalent in C#. But, if I'm being honest, I'm not even sure the previous two lines in my C# equivalent are correct.
Can someone help me figure this one out?
You can convert it like this:
Mat sample = trainSet[0].Data;
Mat mean = Mat.Zeros(sample.Rows, sample.Cols, sample.Depth, sample.NumberOfChannels);
foreach (var person in trainSet)
{
Mat data = person.Data;
for (int i = 0; i < mean.Rows; i++)
{
double meanValue = (double)mean.GetData().GetValue(i, 0);
double personValue = (double)data.GetData().GetValue(i, 0);
meanValue += personValue;
double[] mva = new double[] { meanValue };
Marshal.Copy(mva, 0, mean.DataPointer + i * mean.Cols * mean.ElementSize, 1);
}
}

Accelerate framework "sign" function

I'm trying to find a super fast way of getting the sign of each value in a vector. I was hoping to find a function in the accelerate framework to do this, but couldn't find one. Here's what it would do:
float *inputVector = .... // some audio vector
int length = ...// length of input vector.
float *outputVector = ....// result
for( int i = 0; i<length; i++ )
{
if( inputVector[i] >= 0 ) outputVector[i] = 1;
else outputVector[i] = -1;
}
Ok, I think I've found a way...
vvcopysignf() "Copies an array, setting the sign of each value based on a second array."
So, one method would be to make an array of 1s, then use this function to change the sign of the 1s based on an input array.
float *ones = ... // a vector filled with 1's
float *input = .... // an input vector
float *output = ... // an output vector
int bufferSize = ... // size of the vectors;
vvcopysignf(output, ones, input, &bufferSize);
//output now is an array of -1s and 1s based the sign of the input.

Converting System::Drawing::Bitmap^ to ::MAT

How converting image from picturebox to ::MAT in C++/CLI?
Thank you
You need to cast the Drawing.Image into a Bitmap (assuming that the image REALLY IS a bitmap).
Then lock the System.Drawing.Bitmap, and use the Scan0 property of the BitmapData to access the inner buffer.
System::Drawing::Bitmap ^ bitmapFrame = safe_cast< System::Drawing::Bitmap ^ >(pictureBox1->Image);
BitmapData^ bmpData = bitmapFrame->LockBits(gcnew Rectangle(0, 0, bitmapFrame->Width, bitmapFrame->Height), System::Drawing::Imaging::ImageLockMode::ReadWrite,
bitmapFrame->Format);
try
{
void* data = bmpData.Scan0;
//use the data in the ::Mat constructor.
}
finally { bitmapFrame->UnlockBits(bmpData); }//Remember to unlock!!!

Convert array<System:Byte>^ to Mat

How do I convert an array<System:Byte>^ to a Mat in openCV. I am being passed a array<System:Byte>^ in c++/cli, but I need to convert it to Mat to be able to read it and display it.
You can use constructor Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP). The conversion may look like this.
void byteArray2Mat(array<System::Byte>^ byteArray, cv::Mat &output)
{
pin_ptr<System::Byte> p = &byteArray[0];
unsigned char* pby = p;
char* pch = reinterpret_cast<char*>(pby);
// assuming your input array has 2 dimensions.
int rows = byteArray->GetLength(0);
int cols = byteArray->GetLength(1);
output = cv::Mat(rows, cols, CV_8UC1, (void*)pch)
}
I don't have c++/CLI to test the program and this may not be most efficient method. At least it should give you an idea on how to get started.

Vec3b does not take three arguments?

Im using classes to create a function. The function must find a selected colour in the image provided. So I made it so that the function takes a Vec3b value since it is an RGB value we are talking about.
class colorcompare
{
private:
int threshold;
Vec3b color;
void setcolor(Vec3b);
Mat process(Mat&);
void setthresh(const int);
int getdist(Vec3b);
};
void colorcompare::setcolor(Vec3b colr)
{
color = colr;
}
int _tmain(int argc, _TCHAR* argv[])
{
colorcompare cc1;
Mat image;
image = imread("c:\\car2.jpg", -1);
cc1.setcolor(19,69,139); //This is where im getting error
cc1.setthresh(100);
namedWindow("meh");
imshow("meh", cc1.process(image));
waitKey(0);
return 0;
}
Now the error I am getting is this: 'colorcompare::setcolor' : function does not take 3 arguments
I know that vec3b is a vector of 3 values, so in other words I can access the individual values of vec3b as color[0], color[1] and color[2].
And I know I can define it like such in the function above but it shouldnt the vec3b be able to take 3 values? Like I did in my code?
Classic mistake: the function expects a cv::Vec3b object, not 3 int variables.
If you want a single line solution, try this:
cc1.setcolor(cv::Vec3b(19,69,139));
You defined setColor to take a Vec3b as parameter, so you should give it a Vec3b:
cv::Vec3b color(19,69,139); // or cv::Vec3b color; color[0]=19, ...
cc1.setColor(color);

Resources