Reputation: 5681
I have an image , lets's say 800x800 pixels and I want to define regions of 200x200 pixels and be able to process them.
I can't figure how to make this work. I tried:
int N = 4;
Size smallSize( graySize.width / N ,graySize.height / N );
Mat region_frame;
vector<Mat> smallImages;
namedWindow( "Display window", WINDOW_AUTOSIZE );
for( int i = 0; i < graySize.height - N; i+= smallSize.height )
{
for( int j = 0; j < graySize.width - N; j+= smallSize.width )
{
Rect rect = Rect( j,i, smallSize.width, smallSize.height );
region_frame = grayImg( rect );
smallImages.push_back( region_frame.clone() );
imshow( "Display window", region_frame );
waitKey(0);
}
}
But I am receiving no output ( no windows is created!). If I use imshow to the grayImg ,it is showed correctly.
Also ,because I want to work on these blocks/regions/subimages ,is there a way to assign them a label? For example region[0] ( which will contain pixels 0-199 x 0-199 , region[1] 200-399 x 200-399 and so on.
*********EDIT****************
So , the problem for not showing the image was that above the code I had:
if( grayImg.isContinuous() )
{
graySize.width *= graySize.height;
graySize.height = 1;
}
removing that , the image is shown ok!
Now , remains the handling of smallImages in order to be able to make computations.
For a Mat object I can do for example
float *theData = (float*)grayImg.data;
But for a vector<Mat>
like smallImages?
How can I use a pointer?
Upvotes: 0
Views: 194
Reputation: 41765
If you store each subimage into the smallImages
without cloning:
// Creates a new Mat header that "points" to the subimage
smallImages.push_back(grayImg(rect));
you can directly access the subimage into the main image as usual, like:
// Change the 3-rd subimage to be all 127
smallImages[2].setTo(127);
or using pointers (example in the code below).
Example code:
#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat3b img = imread("D:\\SO\\img\\nice.jpg");
resize(img, img, Size(800, 800));
Mat grayImg;
cvtColor(img, grayImg, COLOR_BGR2GRAY);
grayImg.convertTo(grayImg, CV_32F);
int N = 4;
if (((grayImg.rows % N) != 0) || ((grayImg.cols % N) != 0))
{
// Error
return -1;
}
Size graySize = grayImg.size();
Size smallSize(grayImg.cols / N, grayImg.rows / N);
vector<Mat> smallImages;
for (int i = 0; i < graySize.height; i += smallSize.height)
{
for (int j = 0; j < graySize.width; j += smallSize.width)
{
Rect rect = Rect(j, i, smallSize.width, smallSize.height);
smallImages.push_back(grayImg(rect));
//imshow("Display window", grayImg(rect));
//waitKey(0);
}
}
// Change the 3-rd subimage to be all 127
smallImages[2].setTo(127);
// Iterate on all pixels in 2-nd subimage (will change also the main image)
int idx_smallimage = 1;
float* pdata = (float*)smallImages[idx_smallimage].data;
int step = smallImages[idx_smallimage].step1();
for (int i = 0; i < smallSize.height; ++i)
{
for (int j = 0; j < smallSize.width; ++j)
{
// Assign a random value to pixel (i,j) in subimage
pdata[i * step + j] = rand() & 255;
//smallImages[idx_smallimage](i * smallSize.width + j) = rand()&255;
}
}
return 0;
}
Upvotes: 1
Reputation: 3550
you can test the code i already implemented. maybe you will change it according to your needs.
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
class ImageCells
{
public:
ImageCells(int rows, int cols, int width, int height);
virtual ~ImageCells() {}
int cellwidth() const {return m_width;}
int cellheight() const { return m_height;}
int cols() const { return m_cols;}
int rows() const { return m_rows;}
void setCell( int col, int row, Mat img );
void setImage( Mat img );
Mat getCell( int col, int row );
Mat image;
protected:
int m_width;
int m_height;
int m_cols;
int m_rows;
};
ImageCells::ImageCells( int rows, int cols, int width, int height)
{
image = Mat::zeros( rows * height, cols * width, CV_8UC3);
m_width = width;
m_height = height;
m_cols = cols;
m_rows = rows;
}
void ImageCells::setCell( int col, int row, Mat img )
{
if(img.cols == m_width & img.rows == m_height)
{
Mat roi = image( Rect(col * m_width, row * m_height, m_width, m_height) );
img.copyTo(roi);
}
}
Mat ImageCells::getCell( int col, int row )
{
Mat roi = image( Rect(col * m_width, row * m_height, m_width, m_height) );
return roi.clone();
}
void ImageCells::setImage( Mat img )
{
if(img.cols >= image.cols & img.rows >= image.rows)
img.copyTo(image);
}
int main( int argc, char** argv )
{
ImageCells cells(4,3,70,90); // it creates a ImageCells class having 4 rows and 3 cols, cell witdh = 70 cell height = 90 you can change these values according your needs
Mat img = Mat( 90, 70, CV_8UC3,Scalar(0,0,255)); // a test mat to use with cells.setCell important note is : img witdh&height must be same to cell witdh&height
for(int i=0; i < cells.cols(); i++)
for(int j =0; j < cells.rows(); j++ )
{
cells.setCell(i,j,img); // here you see how to use setCell
randu(img,30*i,160*j); // to show purpose changes img
imshow("cells.image",cells.image);
waitKey();
}
for(int i=0; i < cells.cols(); i++)
for(int j =0; j < cells.rows(); j++ )
{
imshow("cells",cells.getCell(i,j)); // here you see how to use getCell
waitKey();
}
return 0;
}
Upvotes: 0