基础图像处理示例
基础图像处理示例执行脚本位于 ucp_tutorial/vp/vp_samples/script/01_basic_processing 目录下,
该示例展示了如何对图片进行相关的处理,包括图片滤波、图片形态学处理、图片均衡,详细的实现方法请结合示例源码对比实践。
此示例中,直接执行示例脚本会执行默认的图片处理流程:使用sepFilter2D滤波、检测形态学边缘、图片均衡。
若希望更改图片的处理流程,则可以通过在执行示例脚本时追加参数来控制执行的流程,参数的追加规则如下:
sh run_basic_process.sh [filter type] [morphology type]
其中:
- filter type:可选参数,滤波算子。
- morphology type:可选参数,形态学操作。
此外还可以通过追加 -help 命令获取所有可用的追加参数列表。
算子执行后会在 vp_samples/script/01_basic_processing 目录下保存图片处理结果,本示例的生成物内容如下:
vp_samples
└── script // 图片数据目录
└── 01_basic_processing
├── filtered_image.jpg // 滤波后的图片
├── morphology_image.jpg // 形态学变换后的图片
└── equalizeHist_image.jpg // 直方图均衡后的图片
示例的执行流程如下图:
如示例的执行流程图所示,该示例对图片的处理过程可以大致分为以下四个阶段:
-
对加噪后的图片进行滤波。按照滤波算法不同,可分为双线性滤波、盒式滤波、高斯滤波、中值滤波、二维滤波、分离式二维滤波。
-
对滤波后的图片进行形态学处理。按照处理方法不同可分为腐蚀、膨胀、开运算、闭运算、检测边缘。
-
对形态学处理后的图片进行直方图均衡。
图像滤波
在图像滤波环节,示例内将6种滤波算法封装在了对应的函数中,并使用std::map建立字符串与滤波函数的联系,如下图,参数 filter_op 保存了关键字与函数间的映射关系。
typedef int32_t (*example_fn)(hbVPImage &src, hbVPImage &dst);
static std::map<std::string, example_fn> filter_op = {
{"bilateralFilter", bilateral_filter},
{"boxFilter", box_filter},
{"filter2D", filter2D},
{"gaussianBlur", gaussian_blur},
{"medianBlur", median_blur},
{"sepFilter2D", sep_filter2D},
{"default", sep_filter2D}};
在示例代码执行过程中,根据argv参数中的追加关键字不同,自动适配到相应的滤波算法。核心逻辑如下:
/**===============================================================
* process noise image with filter operate
* ===============================================================*/
if (argc > 1) {
ret = filter_op[argv[1]](src, dst);
LOGE_AND_RETURN_IF(0 != ret, HB_UCP_INVALID_ARGUMENT,
"filter operate failed");
} else {
ret = filter_op["default"](src, dst);
LOGE_AND_RETURN_IF(0 != ret, HB_UCP_INVALID_ARGUMENT,
"filter operate failed");
}
以sepFilter2D滤波算法为例,对加噪图片的处理效果如图所示:
滤波前:

滤波后:

形态学处理
形态学处理算子包含了腐蚀、膨胀、开闭运算、顶帽、黑帽等,本示例中通过对 hbVPDilate 和 hbVPErode 接口的调用,封装了其中一部分的形态学功能,具体实现方法请查看函数源码。
与滤波环节类似,此处创建了 morphology_op 参数来存储字符串与形态学函数之间的联系, 代码如下:
static std::map<std::string, example_fn> morphology_op = {
{"dilate", dilate}, {"erode", erode}, {"open", open},
{"close", close}, {"edge", edge}, {"default", edge}};
调度形态学函数时同样采用了字符串适配的方法,核心逻辑如下:
/**===============================================================
* morphology operate
* ===============================================================*/
if (argc > 2) {
ret = morphology_op[argv[2]](src, dst);
LOGE_AND_RETURN_IF(0 != ret, HB_UCP_INVALID_ARGUMENT,
"morphology operate failed");
} else {
ret = morphology_op["default"](src, dst);
LOGE_AND_RETURN_IF(0 != ret, HB_UCP_INVALID_ARGUMENT,
"morphology operate failed");
}
以形态学梯度边缘算法(示例中 edge 函数)为例,对滤波图片的处理效果如图所示:
滤波原图:

形态学梯度边缘检测图:

直方图均衡
为了增强图片的对比度,凸显图片细节,示例通过 equalizeHist 函数,对形态学处理后的图片进行直方图均衡处理。 均衡效果如下图所示:
原图:

均衡后效果图:
