Reputation: 4564
Let's say I have an image of 200x200 pixels. I'd like a 800x800 pixels version where I basically duplicate the 200x200 image and fill the 800x800 image with(Tile the smaller image into the bigger one).
How would you go to do that in openCV? It seems straight-forward, but I don't know how to either create another cv::Mat with the same type as the pattern, but with a bigger size(Canvas size) or if it's possible to take the original 200x200 pixels image and increase it's rows and cols then simply use a loop to paste the corner unto the rest of the image.
I'm using openCV 2.3 btw. I've done quite some processing on images with fixed dimensions, but I'm kind of clueless when it comes to increasing the dimensions of the matrix.
Upvotes: 4
Views: 6723
Reputation: 5960
You can use tile function:
def tile_image(tile, height, width):
x_count = int(width / tile.shape[0]) + 1
y_count = int(height / tile.shape[1]) + 1
tiled = np.tile(tile, (y_count, x_count, 1))
return tiled[0:height, 0:width]
Upvotes: 1
Reputation: 407
In C++, you can just do something like this:
cvx::Mat CreateLargeImage(const cvx::Mat& small, int new_rows, int new_cols) {
// Create a Mat of the desired size, the mat may also be created by resizing of the smaller one.
cvx::Mat result(new_rows, new_cols, 16);
const int sm_rows = small.rows;
const int sm_cols = small.cols;
for (int r = 0; r < result.rows; ++r) {
for (int c = 0; c < result.cols; ++c) {
// use mod operation to effectively repeat the small Mat to the desired size.
result.at<cvx::Vec3b>(r, c)[0] =
small.at<cvx::Vec3b>(r % sm_rows, c % sm_cols)[0];
result.at<cvx::Vec3b>(r, c)[1] =
small.at<cvx::Vec3b>(r % sm_rows, c % sm_cols)[1];
result.at<cvx::Vec3b>(r, c)[2] =
small.at<cvx::Vec3b>(r % sm_rows, c % sm_cols)[2];
}
}
return result;
}
Or you may use openCV's repeat function. e.g,
in Python
import cv2
...
duplicated = cv2.repeat(original, 4, 4)
in C++
cv::Mat original= cv::imread("./benz.jpeg");
cv::Mat duplicated;
cv::repeat(original, 4, 4, duplicated);
Upvotes: 1
Reputation: 6128
FYI- The blog in @karlphillip's response, the basic idea is to use cvSetImageROI
and cvResetImageROI
. Both are C APIs.
In later versions, v2.4 and 3.x for example, one can define a Rect
with the desired location and dimensions and refer to the desired section as img(rect)
.
Example in C API (functional style):
cvSetImageROI(new_img, cvRect(tlx, tly, width, height);
cvCopy(old_img, new_img);
cvResetImageROI(new_img);
In the C++ API using classes:
Mat roi(new_img, Rect(tlx, tly, width, height));
roi = old_img; // or old_img.clone()
Another way in C++ (copies over the image):
old_img.copyTo(new_img(Rect(tlx, tly, width, height)))
Upvotes: 0