概述

本文将深入解析一个基于 C 语言实现的图像旋转算法,核心函数为 Image *Rotation(Image *image)。该算法以灰度或彩色图像为输入,实现了逆时针 45 度旋转,并采用双线性插值保证旋转后图像的平滑性。代码结构清晰,适合学习图像处理基础与算法实现。

代码结构

包含如下核心部分:

  • 图像结构体与操作函数(通过 proto.h 引入)
  • 图像读取与保存:ReadPNMImage、SavePNMImage
  • 图像旋转:Rotation
  • 新图像创建:CreateNewImage
  • 主流程:main、TestReadImage

核心函数:Image *Rotation(Image *image)

算法流程

  1. 新图像创建
    调用 CreateNewImage,输出图像尺寸为原图的 1.5 倍,便于旋转后完整显示。

  2. 中心坐标计算
    原图与输出图像分别计算中心点坐标,用于旋转变换。

  3. 旋转参数计算
    旋转角度为 -45°(逆时针),计算对应的正弦、余弦值。

  4. 逆向映射
    对输出图像每个像素,计算其对应原图位置(逆向旋转),避免空洞。

  5. 双线性插值
    若映射点在原图范围内,采用双线性插值计算像素值,提升旋转后图像质量。

  6. 边界处理
    映射点超出原图范围时,像素值设为 0(黑色)。

关键代码片段

double rad = -45.0 * 3.1415926 / 180.0;
double cosA = cos(rad);
double sinA = sin(rad);

int inCx = inW / 2;
int inCy = inH / 2;
int outCx = outW / 2;
int outCy = outH / 2;

for(int y = 0; y < outH; y++) {
    for(int x = 0; x < outW; x++) {
        double tx = x - outCx;
        double ty = y - outCy;
        double srcX = tx * cosA - ty * sinA + inCx;
        double srcY = tx * sinA + ty * cosA + inCy;

        if(srcX >= 0 && srcX < inW - 1 && srcY >= 0 && srcY < inH - 1) {
            // 双线性插值
            int x1 = (int)floor(srcX);
            int y1 = (int)floor(srcY);
            int x2 = x1 + 1;
            int y2 = y1 + 1;
            double dx = srcX - x1;
            double dy = srcY - y1;
            int p1 = in[y1 * inW + x1];
            int p2 = in[y1 * inW + x2];
            int p3 = in[y2 * inW + x1];
            int p4 = in[y2 * inW + x2];
            double value = p1 * (1 - dx) * (1 - dy) +
                           p2 * dx * (1 - dy) +
                           p3 * (1 - dx) * dy +
                           p4 * dx * dy;
            out[y * outW + x] = (unsigned char)value;
        } else {
            out[y * outW + x] = 0;
        }
    }
}

算法特点

  • 逆向映射:避免旋转后像素空洞,保证每个输出像素都能找到原图对应点。
  • 双线性插值:提升旋转后图像质量,减少锯齿和模糊。
  • 中心化处理:以图像中心为旋转轴,旋转效果自然。

主流程与使用方法

主函数 main 调用 TestReadImage,流程如下:

  1. 读取原图像(如 lena.pgm)
  2. 调用 Rotation 进行旋转
  3. 保存旋转后图像为 rotation.pgm
int main(int argc,char **argv)
{
    const char *file_in="lena.pgm";
    const char *file_out="";
    TestReadImage(file_in,file_out);
    return 0;
}

int TestReadImage(const char *file_in, const char *file_out)
{
    Image *image;
    Image  *rotation;

    image = ReadPNMImage(file_in);
    rotation = Rotation(image);

    SavePNMImage(rotation, (char*)"rotation.pgm");

    return(0);
}

总结

本文以 Image *Rotation(Image *image) 为核心,解析了 C 语言实现的图像旋转算法。该算法采用逆向映射与双线性插值,保证旋转后图像的完整性与质量。适合图像处理初学者深入理解旋转算法原理与实现细节。

参考