红外与可见光金字塔融合 c代码
时间: 2023-09-11 14:05:46 浏览: 121
拉普拉斯金字塔.rar_chargezwe_goosebai_拉普拉斯_拉普拉斯 图像融合_红外与可见光
5星 · 资源好评率100%
以下是一个简单的红外与可见光金字塔融合的C代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define WIDTH 640
#define HEIGHT 480
#define LEVELS 5
// 定义金字塔结构体
typedef struct {
int width;
int height;
int levels;
float **data;
} pyramid;
// 申请金字塔内存空间
void alloc_pyramid(pyramid *p) {
p->data = malloc(p->levels * sizeof(float *));
for (int i = 0; i < p->levels; i++) {
p->data[i] = malloc(p->width * p->height * sizeof(float));
}
}
// 释放金字塔内存空间
void free_pyramid(pyramid *p) {
for (int i = 0; i < p->levels; i++) {
free(p->data[i]);
}
free(p->data);
}
// 生成高斯金字塔
void gaussian_pyramid(float *src, pyramid *dst) {
pyramid tmp = {dst->width, dst->height, dst->levels, NULL};
alloc_pyramid(&tmp);
// 最底层为原图
for (int i = 0; i < dst->width * dst->height; i++) {
tmp.data[0][i] = src[i];
}
// 逐层生成
for (int l = 1; l < dst->levels; l++) {
int w = tmp.width >> l;
int h = tmp.height >> l;
// 高斯核
float kernel[5] = {0.05f, 0.25f, 0.4f, 0.25f, 0.05f};
// 水平方向卷积
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
float sum = 0.0f;
for (int k = 0; k < 5; k++) {
int px = (x << l) + k - 2;
if (px < 0) px = 0;
if (px >= tmp.width) px = tmp.width - 1;
sum += tmp.data[l - 1][y * tmp.width + px] * kernel[k];
}
tmp.data[l][y * w + x] = sum;
}
}
// 垂直方向卷积
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
float sum = 0.0f;
for (int k = 0; k < 5; k++) {
int py = (y << l) + k - 2;
if (py < 0) py = 0;
if (py >= tmp.height) py = tmp.height - 1;
sum += tmp.data[l][py * w + x] * kernel[k];
}
dst->data[l - 1][y * w + x] = sum;
}
}
}
free_pyramid(&tmp);
}
// 生成拉普拉斯金字塔
void laplacian_pyramid(pyramid *src, pyramid *dst) {
pyramid tmp = {src->width, src->height, src->levels, NULL};
alloc_pyramid(&tmp);
// 最高层为原图
for (int i = 0; i < src->width * src->height; i++) {
tmp.data[src->levels - 1][i] = src->data[src->levels - 1][i];
}
// 逐层生成
for (int l = src->levels - 2; l >= 0; l--) {
int w = src->width >> l;
int h = src->height >> l;
// 上采样
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
tmp.data[l][y * w + x] = src->data[l][y * w/2 + x/2];
}
}
// 与高斯金字塔差分
for (int i = 0; i < w * h; i++) {
dst->data[l][i] = src->data[l][i] - tmp.data[l][i];
}
}
free_pyramid(&tmp);
}
// 融合金字塔
void blend_pyramids(pyramid *ir, pyramid *vis, pyramid *dst) {
for (int l = 0; l < ir->levels; l++) {
int w = ir->width >> l;
int h = ir->height >> l;
// 加权平均
for (int i = 0; i < w * h; i++) {
dst->data[l][i] = 0.7f * ir->data[l][i] + 0.3f * vis->data[l][i];
}
}
}
int main() {
// 读取红外图像
FILE *fp = fopen("ir.raw", "rb");
float *ir_data = malloc(WIDTH * HEIGHT * sizeof(float));
fread(ir_data, sizeof(float), WIDTH * HEIGHT, fp);
fclose(fp);
// 读取可见光图像
fp = fopen("vis.raw", "rb");
float *vis_data = malloc(WIDTH * HEIGHT * sizeof(float));
fread(vis_data, sizeof(float), WIDTH * HEIGHT, fp);
fclose(fp);
// 生成高斯金字塔
pyramid ir_gpyr = {WIDTH, HEIGHT, LEVELS, NULL};
alloc_pyramid(&ir_gpyr);
gaussian_pyramid(ir_data, &ir_gpyr);
pyramid vis_gpyr = {WIDTH, HEIGHT, LEVELS, NULL};
alloc_pyramid(&vis_gpyr);
gaussian_pyramid(vis_data, &vis_gpyr);
// 生成拉普拉斯金字塔
pyramid ir_lpyr = {WIDTH, HEIGHT, LEVELS, NULL};
alloc_pyramid(&ir_lpyr);
laplacian_pyramid(&ir_gpyr, &ir_lpyr);
pyramid vis_lpyr = {WIDTH, HEIGHT, LEVELS, NULL};
alloc_pyramid(&vis_lpyr);
laplacian_pyramid(&vis_gpyr, &vis_lpyr);
// 融合金字塔
pyramid blend_pyr = {WIDTH, HEIGHT, LEVELS, NULL};
alloc_pyramid(&blend_pyr);
blend_pyramids(&ir_lpyr, &vis_lpyr, &blend_pyr);
// 重建融合图像
for (int l = blend_pyr.levels - 2; l >= 0; l--) {
int w = blend_pyr.width >> l;
int h = blend_pyr.height >> l;
// 上采样
pyramid tmp = {w, h, 1, NULL};
alloc_pyramid(&tmp);
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
tmp.data[0][y * w + x] = blend_pyr.data[l][y/2 * (w/2) + x/2];
}
}
// 加回差分图像
for (int i = 0; i < w * h; i++) {
tmp.data[0][i] += blend_pyr.data[l + 1][i/4 * (w/2) + (x/2)/2];
}
free(blend_pyr.data[l]);
blend_pyr.data[l] = tmp.data[0];
free_pyramid(&tmp);
}
// 保存融合图像
fp = fopen("blend.raw", "wb");
fwrite(blend_pyr.data[0], sizeof(float), WIDTH * HEIGHT, fp);
fclose(fp);
// 释放内存
free(ir_data);
free(vis_data);
free_pyramid(&ir_gpyr);
free_pyramid(&vis_gpyr);
free_pyramid(&ir_lpyr);
free_pyramid(&vis_lpyr);
free_pyramid(&blend_pyr);
return 0;
}
```
以上代码仅为示例,实际应用中还需要进行很多优化和改进。例如,在金字塔的生成过程中可以使用快速高斯滤波算法加速;在融合金字塔时可以考虑使用多种权重策略。
阅读全文