要求:
根据微分算子的定义,利用模板和图像进行逐像素匹配卷积的方法,求拉普拉斯算子(见模板图)对下图33图像进行边缘检测的结果。要求输出图像的尺寸和原图像一致(边界像素的处理方法选择补零)*
因为两个三x三的矩阵卷积,只能产生一个数字,意义不大。所以在外侧补一圈零。
int targetNum[5][5] = { {0,0,0,0,0} ,
{0,2,7,3,0},
{0,5,8,1,0},
{0,9,2,8,0},
{0,0,0,0,0} };//待卷积矩阵
int coverNum[3][3] = { {0,-1, 0} ,
{-1,4,-1},
{0,-1, 0} };//卷积核
解决方案
主要是通过给矩阵成员下表添加偏移量来实现逐步卷积
#include <iostream>
int main()
{
int targetNum[5][5] = { {0,0,0,0,0} ,
{0,2,7,3,0},
{0,5,8,1,0},
{0,9,2,8,0},
{0,0,0,0,0} };//待卷积矩阵
int coverNum[3][3] = { {0,-1, 0} ,
{-1,4,-1},
{0,-1, 0} };//卷积核
//*****************************************************
int finalNUm[9] = { 0 };
int midNum = 0, finalSum = 0, count = 0;
int movNumX = 0, movNumY = 0;//卷积偏移量
//*****************************************************
while (movNumX<3)
{
for (int row = 0; row < 3; row++)//矩阵行遍历
{
for (int col = 0; col < 3; col++)//矩阵列遍历
{
midNum += targetNum[row + movNumX][col + movNumY] * coverNum[row][col];//对应位置乘积
std::cout << "row=" << row + movNumX << " col=" << col + movNumY << std::endl;
std::cout << "kernal row=" << row << " kernal col=" << col << std::endl;
}
}
std::cout << midNum << std::endl;
finalNUm[count] = midNum;//在一处卷积后的值存入矩阵
count++;
finalSum += midNum;
midNum = 0;//每次开始前要把中间变量清掉
movNumY += 1;//列偏移一列
if (movNumY>2)//如果列偏移到头了,就进行一次行偏移
{
movNumY = 0;
movNumX += 1;
}
}
std::cout << midNum << std::endl;
std::cout << finalSum << std::endl;
for (int n = 0; n < 9; n++)
{
printf("finalNum[%d]=%d ", n, finalNUm[n]);
}
std::cout << std::endl;
std::cout << "Hello World!\n";
}