生成影像金字塔的C语言代码,添加注释
时间: 2023-06-13 08:08:36 浏览: 199
C#编写金字塔图案
以下是生成影像金字塔的C语言代码,其中包含详细注释:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "image.h"
// 函数声明
void pyrDown(image_t *src, image_t *dst);
void pyrUp(image_t *src, image_t *dst);
int main(int argc, char **argv) {
// 加载原始图像
image_t *src = image_load("input.png");
if (src == NULL) {
fprintf(stderr, "Could not load image\n");
return 1;
}
// 创建金字塔图像数组
image_t *pyramid[4];
// 将原始图像作为第一层金字塔
pyramid[0] = src;
// 生成剩余三层金字塔
for (int i = 1; i < 4; i++) {
// 计算当前层的尺寸
int w = pyramid[i - 1]->width / 2;
int h = pyramid[i - 1]->height / 2;
// 创建当前层金字塔图像
pyramid[i] = image_create(w, h, 3);
// 生成当前层金字塔图像
pyrDown(pyramid[i - 1], pyramid[i]);
}
// 保存金字塔图像
for (int i = 0; i < 4; i++) {
char filename[256];
sprintf(filename, "output_%d.png", i);
image_save(pyramid[i], filename);
}
// 释放内存
for (int i = 0; i < 4; i++) {
image_free(pyramid[i]);
}
image_free(src);
return 0;
}
// 函数定义
// 降采样函数,将src图像缩小一半并存储到dst图像中
void pyrDown(image_t *src, image_t *dst) {
// 获取源图像的宽高
int src_w = src->width;
int src_h = src->height;
// 获取目标图像的宽高
int dst_w = dst->width;
int dst_h = dst->height;
// 遍历目标图像的每个像素
for (int y = 0; y < dst_h; y++) {
for (int x = 0; x < dst_w; x++) {
// 计算源图像中对应像素的坐标
int src_x = x * 2;
int src_y = y * 2;
// 计算邻域内像素的平均值
float sum_r = 0, sum_g = 0, sum_b = 0;
for (int j = 0; j < 2; j++) {
for (int i = 0; i < 2; i++) {
int px = src_x + i - 1;
int py = src_y + j - 1;
if (px < 0 || py < 0 || px >= src_w || py >= src_h) {
continue;
}
sum_r += src->data[py][px][0];
sum_g += src->data[py][px][1];
sum_b += src->data[py][px][2];
}
}
int count = 4;
float avg_r = sum_r / count;
float avg_g = sum_g / count;
float avg_b = sum_b / count;
// 存储像素值到目标图像
dst->data[y][x][0] = (unsigned char)avg_r;
dst->data[y][x][1] = (unsigned char)avg_g;
dst->data[y][x][2] = (unsigned char)avg_b;
}
}
}
// 上采样函数,将src图像放大一倍并存储到dst图像中
void pyrUp(image_t *src, image_t *dst) {
// 获取源图像的宽高
int src_w = src->width;
int src_h = src->height;
// 获取目标图像的宽高
int dst_w = dst->width;
int dst_h = dst->height;
// 遍历目标图像的每个像素
for (int y = 0; y < dst_h; y++) {
for (int x = 0; x < dst_w; x++) {
// 计算源图像中对应像素的坐标
float src_x = (float)x / 2;
float src_y = (float)y / 2;
// 取邻域内四个像素的值
int px = (int)floor(src_x);
int py = (int)floor(src_y);
float dx = src_x - px;
float dy = src_y - py;
float c00 = (1 - dx) * (1 - dy);
float c01 = dx * (1 - dy);
float c10 = (1 - dx) * dy;
float c11 = dx * dy;
float r = 0, g = 0, b = 0;
if (px >= 0 && py >= 0) {
r += src->data[py][px][0] * c00;
g += src->data[py][px][1] * c00;
b += src->data[py][px][2] * c00;
}
if (px + 1 < src_w && py >= 0) {
r += src->data[py][px + 1][0] * c01;
g += src->data[py][px + 1][1] * c01;
b += src->data[py][px + 1][2] * c01;
}
if (px >= 0 && py + 1 < src_h) {
r += src->data[py + 1][px][0] * c10;
g += src->data[py + 1][px][1] * c10;
b += src->data[py + 1][px][2] * c10;
}
if (px + 1 < src_w && py + 1 < src_h) {
r += src->data[py + 1][px + 1][0] * c11;
g += src->data[py + 1][px + 1][1] * c11;
b += src->data[py + 1][px + 1][2] * c11;
}
// 存储像素值到目标图像
dst->data[y][x][0] = (unsigned char)r;
dst->data[y][x][1] = (unsigned char)g;
dst->data[y][x][2] = (unsigned char)b;
}
}
}
```
以上代码中,实现了生成四层影像金字塔的功能。其中,`pyrDown`函数是降采样函数,将源图像缩小一半并存储到目标图像中;`pyrUp`函数是上采样函数,将源图像放大一倍并存储到目标图像中。在`main`函数中,先加载原始图像,然后创建金字塔图像数组,并将原始图像作为第一层金字塔,接着生成剩余三层金字塔,最后保存金字塔图像并释放内存。
阅读全文