众所周知,OpenCV提供了生成卷积核函数:getStructuringElement(),该函数可以生成三种卷积核,分别为RECT(矩形),CROSS(十字交叉型),ELLIPSE(椭圆形)。但在实际的应用中,可能会用到菱形的卷积核,本文提供了使用OpenCV生成菱形卷积核的代码,由C++编写。
不同卷积核的区别见下图(以5x5为例,其中绿色为1,白色为0):
函数代码:
Mat GetDiamondKernel(const int size)
{
Mat kernel = Mat_<uchar>(size, size);
if (size < 2)return kernel = (Mat_<uchar>(1, 1) << 1);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
int num_1 = i * 2 + 1;
double num_0 = size - num_1;
if (i < size / 2 + 1) {
if (j < num_0 / 2 || j >= num_0 / 2 + num_1)
kernel.ptr<uchar>(i)[j] = 0;
else
kernel.ptr<uchar>(i)[j] = 1;
}
else kernel.ptr<uchar>(i)[j] = kernel.ptr<uchar>(size - i - 1)[j];
}
}
return kernel;
}
函数 GetDiamondKernel(),参数为卷积核尺寸,输出Mat型的卷积核kernel。
测试用例:
#include<iostream>
#include"./opencv/include/opencv2/highgui.hpp"
#include"./opencv/include/opencv2/opencv.hpp"
using namespace cv;
using namespace std;
//生成菱形卷积核函数
Mat GetDiamondKernel(const int size)
{
Mat kernel = Mat_<uchar>(size, size);
if (size < 2)return kernel = (Mat_<uchar>(1, 1) << 1);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
int num_1 = i * 2 + 1;
double num_0 = size - num_1;
if (i < size / 2 + 1) {
if (j < num_0 / 2 || j >= num_0 / 2 + num_1)
kernel.ptr<uchar>(i)[j] = 0;
else
kernel.ptr<uchar>(i)[j] = 1;
}
else kernel.ptr<uchar>(i)[j] = kernel.ptr<uchar>(size - i - 1)[j];
}
}
return kernel;
}
int main()
{
//生成5x5大小菱形卷积核
Mat kernel = GetDiamondKernel(5);
//生成7x7大小菱形卷积核
Mat kernel2= GetDiamondKernel(7);
//打印结果
cout << "kernel:" << endl << kernel << endl << endl;
cout << "kernel2:" << endl << kernel2 << endl << endl;
return 0;
}
输出结果:
成功生成了菱形卷积核!