c++ - 图像旋转




C/C++中的图像缩放和旋转 (7)

CxImage是一个免费的库,用于处理图像,它可以做你想做的。 除了微不足道的东西,我没有亲自使用它,但我已经看到它反复推荐。

缩放2D图像数组的最佳方法是什么? 例如,假设我有一个1024 x 2048字节的图像,每个字节都是一个像素。 每个像素都是从0到255的灰度级别。我希望能够通过任意因子来缩放此图像并获得新图像。 所以,如果我按0.68的比例缩放图像,我会得到一个尺寸为0.68 * 1024 x 0.68 * 2048的新图像。 一些像素将相互折叠。 而且,如果按照3.15的系数进行缩放,则会得到像素重复的较大图像。 那么,完成这个的最好方法是什么?

接下来,我希望能够以0到360度(0 - 2Pi)范围内的任意角度旋转图像。 旋转后裁剪图像不是问题。 什么是最好的方法来做到这一点?


你想自己做这个肮脏的工作,或ImageMagick可以帮你吗?


复制或丢弃像素不是最好的方法或图像调整大小,因为结果将显示像素化和jagginess。 为了获得最佳效果,您应该对图像进行重新采样 ,从而使得图像看起来更平滑。 有很多重采样的方法,比如双线性,双三次,lanczos等等。

看看wxWidgets中的BicubicResample函数。 它的作品将各种图像,不仅灰度,但你应该能够适应你的需求。 然后还有来自VirtualDub的重新采样代码。 Google Codesearch可能会显示更多相关的代码。

编辑:链接在预览中看起来不错,但张贴时被打破。 这很奇怪。 去谷歌代码搜索和分别查询“wxwidgets resamplebicubic”和“virtualdub resample”得到相同的结果。


没有“简单”的方式来表达这一点。 缩放和旋转都不是“微不足道”的过程。

谷歌它的二维图像库。 Magick ++可以作为divideandconquer.se的观点,但也有其他的。


point scaling(point p,float sx,float sy) {
    point s;

    int c[1][3];
    int a[1][3]={p.x,p.y,1};
    int b[3][3]={sx,0,0,0,sy,0,0,0,1};

    multmat(a,b,c);

    s.x=c[0][0];
    s.y=c[0][1];

    return s;
}

查看英特尔性能基元 。 我之前使用过它,它在x86上产生接近最佳的性能。 还有一个测试程序,可以使用各种算法。


目前还没有提到,所以我将指出,OpenCV具有缩放和旋转图像的功能,以及大量的其他实用程序。 它可能包含许多与这个问题无关的特性,但是对于这种类型的库很容易设置和使用。

您可以尝试手动实现这种转换,但缩放和旋转的简单方法通常会导致明显的细节丢失。

使用OpenCV,缩放可以这样完成:

float scaleFactor = 0.68f;
cv::Mat original = cv::imread(path);
cv::Mat scaled;
cv::resize(original, scaled, cv::Size(0, 0), scaleFactor, scaleFactor, cv::INTER_LANCZOS4);
cv::imwrite("new_image.jpg", scaled);

这使用Lanczos插值将图像缩小0.68倍。

我不太熟悉旋转,但这里是OpenCV网站上的一个教程的一个例子的一部分,我已经编辑了相关的部分。 (原来有歪斜和翻译...)

/// Compute a rotation matrix with respect to the center of the image
Point center = Point(original.size().width / 2, original.size().height / 2);
double angle = -50.0;
double scale = 0.6;

/// Get the rotation matrix with the specifications above
Mat rot_mat( 2, 3, CV_32FC1 );
rot_mat = getRotationMatrix2D(center, angle, scale);

/// Rotate the image
Mat rotated_image;
warpAffine(src, rotated_image, rot_mat, src.size());

OpenCV网站

他们也有一些非常好的文档。





image-scaling