目标
在进行图像处理操作之前,首要任务是确保能够正确地读取图像。编写纯 C 语言代码进行图像处理时,不太适宜使用 OpenCV2。因此,为了遵循标准且便于操作,我们采用 libpng 的代码库来实现对 PNG 图像的读写。之所以选择在 Linux 系统下进行此项操作,主要是因为许多库在 Linux 环境下的安装更为便捷,例如 libpng。而在 Windows 系统下,需要下载源码、进行编译以及配置路径等一系列操作,极为繁琐,这与我们进行算法学习的初衷背道而驰。对于那些在 Windows 系统下不想安装双系统的用户,可以使用 WSL(Windows Subsystem for Linux),这对于代码学习而言也十分便利,仅需使用 Visual Studio Code 进行链接即可。
实际代码
我们首先对图像进行读取操作,以获取图像的高度(h)、宽度(w)以及通道数(c),并进行输出,同时将数据重新写入以生成一张新的图像。在使用过程中,要求系统中已安装 libpng 库,并且在源文件中利用了他人编写好的 io_png.c 和 io_png.h 文件。
文件结构如下:为了方便查阅文件中的函数,将.c与.h文件放在了同一文件夹下。
main文件中并没有太多内容,仅仅是简单地调用了两个函数
io_png_read_f32函数输入了一个字符串,和三个变量,最后获得图像文件的整体数据和HWC信息。得到的数据是一个一维数组。
io_png_write_f32则根据输入的数据以及HWC生成图片并保存。
#include <stdio.h>
#include "io_png.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h> // 在gcc编译器中,使用的头文件因gcc版本的不同而不同
void main()
{
char *image_path = "you png path";
char *save_path = "you png save path";
float *U = NULL;
/* Size of the input image: N2xN1 matrix */
size_t N2,N1;/* N2=number of rows (dx2) and N1=number of columns (dx1) */
size_t Nc; /* Number of channels */
size_t NNc; /* Total size of the image: N2xN1xNc */
int flag;
U = io_png_read_f32(image_path, &N1, &N2, &Nc);
printf("image size is (%d, %d, %d)", (int)N1, (int)N2, (int)Nc);
flag = io_png_write_f32(save_path, U, N1, N2, Nc);
printf("flag is %d \n ", flag);
}
io_png的相关文件有点冗长,所以放在github中。
CMakeLists.txt的代码如下,重点是png的链接库记得加上,否则运行会报找不到对应的png函数。
cmake_minimum_required(VERSION 3.22)
project(val_test)
#debug版本才能调试
SET(CMAKE_BUILD_TYPE "Debug")
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
# 声明包含的*.c和*.h文件
set(HOME you_project_path)
file(GLOB SRC ${HOME}/src/*.c)
include_directories(${HOME}/src /usr/local/include)
# 声明可执行程序输出位置
set(EXECUTABLE_OUTPUT_PATH ${HOME}/output)
# # 指定库路径
# link_directories(${HOME}/static)
# 引用静态库,掐头去尾写中间 libxxx.a,要放在生成可执行程序前。
link_libraries(png m)
# 输出相关信息
message(STATUS "src files list: ${SRC}")
message(STATUS "HOME path: ${HOME}")
# 生成可执行程序
add_executable(main ${SRC})
要进行调试的话参考我之前问文章:
链接: 使用cmake编译后并debug可执行文件
上述代码运行后会在指定位置生成图像的复制,我们也可以改变N1,N2的值,查看结果。(会将图像的一部分数据保存为图像,生成不清晰的扭曲图)
代码保存在链接: github中的c_code里