I do not understand why I am getting core dumped here:
int nrows = 480, ncols = 640;
cv::Mat m3_8u;
// Create a variable of type cv::Mat* named m3_8u which has three channels with a
// depth of 8bit per channel. Then, set the first channel to 255 and display the result.
m3_8u.create(nrows, ncols, CV_8UC3);
for (int i=0; i<nrows; i++){
for (int j=0; j<ncols; j++){
m3_8u.at<cv::Vec3f>(i,j)[0] = 255;
}
}
I want to change all the values from the first color dimension.
Related
I came across this sample code on openCV library. What does the line p[j] = table[p[j]] do? I have come across multi dimensional arrays but not something like this before.
Mat& ScanImageAndReduceC(Mat& I, const uchar* const table)
{
// accept only char type matrices
CV_Assert(I.depth() == CV_8U);
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols * channels;
if (I.isContinuous())
{
nCols *= nRows;
nRows = 1;
}
int i,j;
uchar* p;
for( i = 0; i < nRows; ++i)
{
p = I.ptr<uchar>(i);
for ( j = 0; j < nCols; ++j)
{
p[j] = table[p[j]];
}
}
return I;
}
It is doing color replacement by using a table where each pixel intensity maps to some other value. Commonly used for techniques like color grading, histogram adjustment, or even thresholding.
Here, the table contains unsigned char values and is being indexed by the value of the pixel. The pixel's intensity p[i] is used as an index into the table, and the value at that index is then written to that pixel, replacing its original value.
It is a lookup table conversion.
The pixels of image(I) would be converted by means of table.
For example, the pixel with value 100 would be changed to 10 if table[100]=10.
Your sample code is introduced in OpenCV tutorial which is well explained of what the code does.
https://docs.opencv.org/master/db/da5/tutorial_how_to_scan_images.html
I have an array of images as follows:
int width = 5, height = 4, n = 3; // example --> 3 images of size 5x4
int sz[] = {width, height, n};
cv::Mat array(3, sz, CV_8UC1, cv::Scalar::all(0));
Now I would like to display the images. I tried something like this:
char winName[20];
for (int i = 0; i < n; i++)
{
sprintf(winName, "image %d", i);
cv::imshow(winName, array.data[i]);
}
which I got from here: http://answers.opencv.org/question/28184/show-many-images-in-different-windows-in-a-loop-using-one-imshow-command/
And I thought about using a for each, in expression, but couldn't get that running. I'm not quite sure on how to manage 3 dimensions of the array. Could you please provide me with some information on how to solve that problem? Many thanks in advance.
Try something like this:
// create a vector of Mats
std::vector<cv::Mat> images(3);
// initialize each image somehow, for example with black images
for(size_t i = 0; i < images.size(); ++i)
images[i] = cv::Mat::zeros(4, 5, CV_8U);
// show each image
for(size_t i = 0; i < images.size(); ++i) {
char winName[20];
sprintf(winName, "image %d", i);
cv::imshow(winName, images[i]);
}
// wait until a key is pressed before exiting
cv::waitKey();
I want to do an operation like this however I cannot get the values of the vector Mat and change them. table is a 1 dimensional array by the way. Thanks.
vector<Mat> orjchannel;
vector<Mat> refchannel;
// There are some functions here
for (int i = 0; i < 512; i++){
for (int j = 0; j < 512; j++){
double value = refchannel[i][j]; // This part does not work
orjchannel[i][j] = tables[value];
With OpenCV, you typically access the values of a Mat with the at<DATATYPE>(r,c) command. For example...
// Mat constructor
Mat data(4, 1, CV_64FC1);
// Set Value
data.at<double>(0,0) = 4;
// Get Value
double value = data.at<double>(0,0);
I'm not certain about my mean function. In Matlab, the mean of my image is 135.3565 by using mean2; however, my function gives 140.014 and OpenCV built-in cv::mean gives me [137.67, 152.467, 115.933, 0]. This is my code.
double _mean(const cv::Mat &image)
{
double N = image.rows * image.cols;
double mean;
for (int rows = 0; rows < image.rows; ++rows)
{
for (int cols = 0; cols < image.cols; ++cols)
{
mean += (float)image.at<uchar>(rows, cols);
}
}
mean /= N;
return mean;
}
My guess is that you are feeding one type of image to Matlab and another type to your algoritm and to the opencv built-in function.
The mean2 function of Matlab takes a 2D image (grayscale) . Your function assumes that the image is 2D matrix of unsigned chars (grayscale too), and when you do this:
mean += (float)image.at<uchar>(rows, cols);
and you pass a color image to the function, an incorrect value is retrieved. Try to convert your image to grayscale before passing to your function and compare the result with Matlab.
For a color image, modify your function to this:
double _mean(const cv::Mat &image)
{
double N = image.rows * image.cols * image.channels();
double mean;
for (int rows = 0; rows < image.rows; ++rows)
{
for (int cols = 0; cols < image.cols; ++cols)
{
for(int channels = 0; channels < image.channels(); ++channels)
{
mean += image.at<cv::Vec3b>(rows, cols)[channels];
}
}
}
mean /= N;
return mean;
}
and in Matlab compute the mean with
mean(image(:))
which will vectorize your image before compute the mean. Compare the results.
The opencv function computes the mean of each channel of the image separately, so the result is a vector of the means of each channel.
I hope this will help!
I load an image in grayscale mode into Mat image. I use image.convertTo(image, CV_32F);
to convert the data type to double. I would like to convert the image into a vector<double>, so I iterate through the matrix in the following way:
int channels = image.channels();
int nRows = image.rows;
int nCols = image.cols;
vector<double> vectorizedMatrix (nRows*nCols);
if (image.isContinuous()) {
nCols *= nRows;
nRows = 1;
}
double* pI;
int k = 0;
for (int i=0; i<nRows; i++) {
pI = image.ptr<double>(i);
for (int j=0;j<nCols;j++) {
vectorizedMatrix.at(k) = pI[j];
k++;
}
}
return vectorizedMatrix;
When checking the data I get, I see huge values in the area of 10^10, which cannot be. Am I iterating wrongly through the matrix or does the function convertTo do something I'm not aware of?
"I use image.convertTo(image, CV_32F); to convert the data type to double"
no, that will convert to float. if you want double, instead use:
image.convertTo(image, CV_64F);