Let's say that I have a 9-by-9 2-D array. Is there a difference between looping through with a single loop or multiple loops?
for (int i = 0; i < 81; i++)
currentEdit[i / 9][i % 9] = 0;
VS.
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
currentEdit[i][j] = 0;
The right choice is multiple loops. Keep in mind that it will perform much less operations since it does not have to divide or calculate the module to access the array position.
This is the right choice:
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
currentEdit[i][j] = 0;
Is there a possibility to use a boost matrix along FFTW? if so how do you do it?
what i basically have is
QPixmap pixmap("lena.bmp");
// resize input image
pixmap = pixmap.copy(512,512,128,128);
pixmap = pixmap.scaled(128,128);
QImage image = pixmap.toImage();
QRgb col;
int g;
int width = pixmap.width();
int height = pixmap.height();
matrix<double> m(width,height);
for (int j = 0; j < m.size2(); j++)
{
for (int i = 0; i < m.size1(); i++)
{
m(i,j) = 0;
m(i,j) = qGray(image.pixel(i,j));
}
}
I want to perform FFTW on the matrix 'm' and then redisplay the fft of the image. how do i do this?
you can do is first read your image into an array, then apply the FFTW as per your needs on this array and then fill this array into a boost ublas matrix and then use it.
int a[width][height];
for (int j = 0; j < width; j++)
{
for (int i = 0; i < height; i++)
{
a[i][j] = qGray(image.pixel(i,j));
}
}
//apply fftw
matrix<double> m(width,height);
for (int j = 0; j < width; j++)
{
for (int i = 0; i < height; i++)
{
m(i,j) = fft_a[i][j];
}
}
I hope this works
I want to count the number of white points in a background image which is only black and white. I have a code like this:
int count = 0;
for ( int j = 0; j < Image.rows; j ++ )
{
for ( int i = 0; i < Image.cols; i ++ )
{
if ( Image.at<int>(i,j) >= 150 )
{
count ++ ;
}
}
}
For some reason, the above code doesn't work, it just stops reacting. I checked, and the line" if ( Image.at(i,j) >= 150 ) " causes the problem. My "Image" is a "cv::Mat", with "CV_8UC3" type. Is there someone can help me? Thank you.
In addition to my comment to Robin's answer, your error is that you try to access an image of CV_8UC3 type as ints. If you want to check grey levels, do something like this (note the "unsigned char" instead of "int", as in Robin's answer).
cv::Mat greyscale;
cv::cvtColor(image,grayscale,CV_RGB2GRAY);
// either, most elegant:
int count = cv::countNonZero(greyscale >= 150);
// or, copied from Robin's answer:
int count = 0;
for(int i = 0; i < greyscale.rows; ++i) {
const unsigned char* row = greyscale.ptr<unsigned char>(i);
for(int j = 0; j < greyscale.cols; j++) {
if (row[j] >= 150)
++count;
}
}
I believe this is much neater:
Mat result;
threshold(Image,result,150,255,THRESH_BINARY);
int white_count = countNonZero(result);
Write Image.at<unsigned char>(j,i) not Image.at<unsigned char>(i,j) if you are using i for cols and j for rows.
I think you have to access the row before the column, meaning you should swap i and j.
Substitute if ( Image.at<int>(i,j) >= 150 ) with if ( Image.at<int>(j,i) >= 150 )
There are easier ways to access a Mat though.
OpenCV provides an STL-like iterator which is easy to use and if you want to access all the elements very easy to use. Example:
int count = 0;
MatConstIterator_<int> it = Image.begin<int>(), it_end = Image.end<int>();
for(; it != it_end; ++it)
if ((*it) >= 150)
++count;
Last but not least you could also get a pointer to each row and access the data via the plain [] operator:
int count = 0;
for(int i = 0; i < Image.rows; ++i) {
const int* Ii = Image.ptr<int>(i);
for(int j = 0; j < Image.cols; j++) {
if (Ii[j] >= 150)
++count;
}
}
you could access the CV_8UC3 Pixels with opencv bytes vectors (unsigned char pixels) !
In this case you can make the following (now you could also use some special color threshold)
int channel = 0;
Image.at<Vec3b>( row , col )[channel]
There are a lot of methods to access the cv::Mat image,
if you want to directly access the color image(CV_8UC3),
it could be implemented by following:
int count = 0;
int threshold = 150;
for(int j = 0; j < img.rows; j++) {
for(int i = 0; i < img.cols; i++) {
//white point which means that the point in every channel(BGR)
//are all higher than threshold!
if(img.ptr<cv::Vec3b>(j)[i][0] > threshold &&
img.ptr<cv::Vec3b>(j)[i][1] > threshold
img.ptr<cv::Vec3b>(j)[i][2] > threshold ) {
count++;
}
}
}
but I recommend that if you only want to count white points, you can just convert image into grayscale
(CV_8UC1), and do as following:
cv::Mat img;
cv::cvtColor(src,img,CV_BGR2RGB);
int count = 0;
int threshold = 150;
for(int j = 0; j < img.rows; j++) {
for(int i = 0; i < img.cols; i++) {
if(img.ptr<uchar>(j)[i] > threshold) {
count++;
}
}
}
Finally, note that access cv::Mat image by img.ptr< Imagetype> will not check the accessed point is correct, so if you certainly know the range of image, the access image by ptr will be fine, otherwise, you can do by img.at< Imagetype>(), it will check every point is correct at every call,why access image by ptr is faster
so if there are invalid accessed point, it will assert you!
What is the simplest way to modify a direct x,y location of a cv::Mat object? I have a cv::Mat called 'temp' which has an image in it, and what if I wanted to turn each pixel pink, one by one?
I tried something of the following:
for (int i = 0; i < temp.size().width; i++)
{
for (int j = 0; j < temp.size().height; j++)
{
temp.at(cv::Point(i, j)) = 255;
cv::waitKey();
}
}
but that won't even compile..
The way to use at in this case is temp.at<unsigned char>(i, j).
Here is an example :
Mat H(100, 100, CV_64F);
for(int i = 0; i < H.rows; i++)
for(int j = 0; j < H.cols; j++)
H.at<double>(i,j)=1./(i+j+1);
For the complete description look here: http://opencv.itseez.com/modules/core/doc/basic_structures.html#mat-at
i'm trying to initialize all cells of a matrix with NULL values, but something is wrong here.
the code :
vector<vector<Distance*> > distanceMatrix;
for (int i = 0; i < 7 ; i++)
for (int j = 0; j < 7 ; j++)
distanceMatrix[i][j].push_back(NULL);
i bet it's something stupid, thanks for the help.
From the std::vector reference page:
Vectors can be constructed with some values in them.
You may try:
vector<vector<Distance*> > distanceMatrix(7, vector<Distance*>(7, NULL));
Also, regarding your problem:
vector<vector<Distance*> > distanceMatrix;
for (int i = 0; i < 7 ; i++)
for (int j = 0; j < 7 ; j++)
distanceMatrix[i][j].push_back(NULL); //1
When you code first reach //1, distanceMatrix[i] resolves to distanceMatrix[0] but you did not call distanceMatrix.push_back(vector<Distance*>()) so you are referring to a non initialized cell.
To correct code would have been:
vector<Distance*> vec;
for (int j = 0; j < 7 ; j++)
vec.push_back(NULL);
vector<vector<Distance*> > distanceMatrix;
for (int i = 0; i < 7 ; i++)
{
distanceMatrix.push_back(vec);
}
Which is still far worse than my first suggestion.
Since the matrix is empty to begin with, you need to push_back every value and every row, not depending on its position in the matrix:
vector<Distance*> row;
for(int j=0; j < 7; j++)
row.push_back(NULL);
vector<vector<Distance*> > distanceMatrix;
for(int i=0; i < 7; i++)
distanceMatrix.push_back(row);