Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save cv::imwrite in different name in the loop

everyone I just referenced a rotating image sample from: Rotate an image without cropping in OpenCV in C++

#include "opencv2/opencv.hpp"

int main()
{
    cv::Mat src = cv::imread("im.png", CV_LOAD_IMAGE_UNCHANGED);
    double angle = -45;

    // get rotation matrix for rotating the image around its center
    cv::Point2f center(src.cols/2.0, src.rows/2.0);
    cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0);
    // determine bounding rectangle
    cv::Rect bbox = cv::RotatedRect(center,src.size(), angle).boundingRect();
    // adjust transformation matrix
    rot.at<double>(0,2) += bbox.width/2.0 - center.x;
    rot.at<double>(1,2) += bbox.height/2.0 - center.y;

    cv::Mat dst;
    cv::warpAffine(src, dst, rot, bbox.size());
    cv::imwrite("rotated_im.png", dst);

    return 0;
}

Code tested with opencv 2.4.9 (visual c++ 2010)

For me, I want to let the angle be alternative, that means I want to change it from 0 to 360. And import each images out. Like this:

#include "opencv2/opencv.hpp"

int main()
{	for (double i=0;i<361;i++)
{
    cv::Mat src = cv::imread("refshape.bmp", CV_LOAD_IMAGE_UNCHANGED);
    double angle = -i;

    // get rotation matrix for rotating the image around its center
    cv::Point2f center(src.cols/2.0, src.rows/2.0);
    cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0);
    // determine bounding rectangle
    cv::Rect bbox = cv::RotatedRect(center,src.size(), angle).boundingRect();
    // adjust transformation matrix
    rot.at<double>(0,2) += bbox.width/2.0 - center.x;
    rot.at<double>(1,2) += bbox.height/2.0 - center.y;

    cv::Mat dst;
    cv::warpAffine(src, dst, rot, bbox.size());
    cv::imwrite("rotated_im.png", dst);
}
    return 0;
}

========================================= It's easy to change the angle, but the import part is the challenge for me. I wants have 360 results in my file, how can I do for it? I tried to modify this line: cv::imwrite("rotated_im.png", dst); to cv::imwrite("rotated_im_%d.png", i , dst);

It doesn't work for it.

like image 581
Hsu Yu-Wei Auston Avatar asked Jan 10 '23 07:01

Hsu Yu-Wei Auston


1 Answers

You will need to create a string each time through the loop with your desired file name and pass that to cv::imwrite. The easiest way to do that in C++ is with a std::ostringstream. Replace the last line (the cv::imwrite) of your loop body with:

std::ostringstream name;
name << "rotated_im_" << i << ".png";
cv::imwrite(name.str(), dst);

You will need to add #include <sstream> at the top with your other includes. String streams work just like other iostreams (such as std::cout and fstreams if you are familiar with those).

Also, I would not use a double in a for loop like that. If you want to count by one, use an integer and then convert it to a double if you need to use it as a double. Since you are doing that (with double angle = -i;), just change your for loop header to be:

for (int i =0; i <= 360; i++)

This will also make your output filenames look more like I suspect you want them. If i is a double, you may get file names like rotated_im_5.000000.png.

like image 164
plasmoidia Avatar answered Jan 11 '23 20:01

plasmoidia