#include <opencv2/opencv.hpp>
cv::Mat rotateAndTile(const cv::Mat& src, double angle) {
// 计算旋转矩阵和旋转后的图像大小
cv::Point2f src_center(src.cols / 2.0, src.rows / 2.0);
cv::Mat rot_mat = cv::getRotationMatrix2D(src_center, angle, 1.0);
cv::Rect bbox = cv::RotatedRect(src_center, src.size(), angle).boundingRect();
// 调整旋转矩阵以适应新图像的中心
cv::Mat adjust_rot_mat = rot_mat;
adjust_rot_mat.at<double>(0, 2) += (bbox.width / 2) - src_center.x;
adjust_rot_mat.at<double>(1, 2) += (bbox.height / 2) - src_center.y;
// 初始化目标图像
cv::Mat dst(bbox.height, bbox.width, src.type(), cv::Scalar::all(255));
// 旋转并填充到目标图像
cv::warpAffine(src, dst, adjust_rot_mat, dst.size(), cv::INTER_LINEAR, cv::BORDER_TRANSPARENT);
return dst;
}
cv::Mat processLargeImage(const cv::Mat& image, int block_height, double angle) {
int block_width = image.cols;
cv::Size resultSize = cv::RotatedRect(cv::Point2f(image.cols/2.0, image.rows/2.0), image.size(), angle).boundingRect().size();
cv::Mat result = cv::Mat::zeros(resultSize, image.type());
for (int y = 0; y < image.rows; y += block_height) {
cv::Rect roi(0, y, image.cols, std::min(block_height, image.rows - y));
cv::Mat block = image(roi);
// 旋转块
cv::Mat rotatedBlock = rotateAndTile(block, angle);
// 将旋转后的块复制到结果图像。
cv::Rect rotatedRoi(0, y, rotatedBlock.cols, rotatedBlock.rows);
rotatedBlock.copyTo(result(rotatedRoi));
}
return result;
}
int main() {
cv::Mat image = cv::imread("bigpicture.tif", cv::IMREAD_UNCHANGED);
if (image.empty()) {
return 0;
}
int block_height = 100;
double angle = 75;
// 处理大图
cv::Mat processed = processLargeImage(image, block_height, angle);
// 保存处理后的图像
cv::imwrite("output.tif", processed);
}
- **对于内存占用建议**:尽量避免同时在内存中加载处理完整图片。在代码中已通过 `roi` 机制和按行处理分块。除此之外,你还可以:
- 使用 OpenCV 的 `cv::UMat` 这一类来代替 `cv::Mat`,其底层利用了 OpenCL,可以在 GPU 上执行操作。
- 避免做不必要的拷贝。
- 如有可能,考虑对最终的处理结果按块进行处理和保存,这样也可以降低内存的占用。
- **修正**:修正了 `adjustRotMat.at<double>` 中模板类型的问题以确保矩阵操作正确(调整了函数部分)。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |