基础图像处理示例

基础图像处理示例执行脚本位于 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 // 直方图均衡后的图片

示例的执行流程如下图:

VP6_01Flow

如示例的执行流程图所示,该示例对图片的处理过程可以大致分为以下四个阶段:

  1. 对加噪后的图片进行滤波。按照滤波算法不同,可分为双线性滤波、盒式滤波、高斯滤波、中值滤波、二维滤波、分离式二维滤波。

  2. 对滤波后的图片进行形态学处理。按照处理方法不同可分为腐蚀、膨胀、开运算、闭运算、检测边缘。

  3. 对形态学处理后的图片进行直方图均衡。

图像滤波

在图像滤波环节,示例内将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滤波算法为例,对加噪图片的处理效果如图所示:

滤波前:

image

滤波后:

image

形态学处理

形态学处理算子包含了腐蚀、膨胀、开闭运算、顶帽、黑帽等,本示例中通过对 hbVPDilatehbVPErode 接口的调用,封装了其中一部分的形态学功能,具体实现方法请查看函数源码。 与滤波环节类似,此处创建了 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 函数)为例,对滤波图片的处理效果如图所示:

滤波原图:

image

形态学梯度边缘检测图:

image

直方图均衡

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

原图:

image

均衡后效果图:

image