前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图像的卷积操作

图像的卷积操作

作者头像
全栈程序员站长
发布2022-09-01 11:15:52
3170
发布2022-09-01 11:15:52
举报

大家好,又见面了,我是你们的朋友全栈君。

原理:

给定一个奇数尺寸大小的卷积核,对图像进行卷积操作。

因为使用奇数尺寸大小的卷积核,其锚点正好在卷积核正中央的位置。

如下图

在这里插入图片描述
在这里插入图片描述

中间画了一个锚的就是锚点

使锚点覆盖在待计算像素上面,然后计算像素值与被覆盖的卷积核中的值的乘积和。将这个和赋值给当前像素,这就是卷积的过程。

公式如下所示

在这里插入图片描述
在这里插入图片描述

此处会有一个问题,如果锚点落在第一个像素点(1,1)上,卷积核当中锚点左侧和上方的卷积值超出了图像的边界外,怎么处理?

这里使用最原始的办法,即将待处理的图片增加一圈边缘,这个边缘正好宽度正好是卷积核尺寸除以2再取整的值,这样一个图像就多了一圈像素值为0的黑框。

可以进行卷积操作了。

在opencv 的函数库当中,有filter2D这么个函数,咱们现在山寨他一个!

代码:

代码语言:javascript
复制
void Filter2D(const Mat &src, Mat &dst,int ksize,short *kernel)//参数分别为原始图像,目标图像,卷积核尺寸,卷积核,只读入16位图像哦! { 
     CV_Assert(ksize % 2 == 1); Mat tmp; int len = ksize / 2; tmp.create(Size(src.cols + len, src.rows + len), src.type());//添加边框 dst.create(Size(src.cols, src.rows), src.type()); int channel = src.channels(); uchar *ps = src.data; uchar *pt = tmp.data; for (int row = 0; row < tmp.rows; row++)//添加边框的过程 { 
     for (int col = 0; col < tmp.cols; col++) { 
     for (int c = 0; c < channel; c++) { 
     if (row >= len && row < tmp.rows - len && col >= len && col < tmp.cols - len) pt[(tmp.cols * row + col)*channel + c] = ps[(src.cols * (row - len) + col - len) * channel + c]; else pt[(tmp.cols * row + col)*channel + c] = 0; } } } uchar *pd = dst.data; pt = tmp.data; for (int row = len; row < tmp.rows - len; row++)//卷积的过程 { 
     for (int col = len; col < tmp.cols -len; col++) { 
     for (int c = 0; c < channel; c++) { 
     short t = 0; for (int x = -len; x <= len; x++) { 
     for (int y = -len; y <= len; y++) { 
     t += kernel[ (len+x) * ksize + y + len] * pt[((row + x) * tmp.cols + col + y) * channel + c]; } } pd[(dst.cols * (row - len) + col - len) * channel + c] = saturate_cast<ushort> (t);//防止数据溢出ushort是16为数据 } } } } int main() { 
     ios::sync_with_stdio(false); Mat src = imread("src.jpg"); Mat dst; short m[9] = { 
     0, -1, 0 ,-1,4,-1, 0 ,-1,0}; Filter2D(src, dst, 3, m); imshow("src", src); imshow("dst", dst); waitKey(); system("pause"); return 0; } 

结果:

src图像是

在这里插入图片描述
在这里插入图片描述

卷积后的图像

在这里插入图片描述
在这里插入图片描述

这里使用的卷积核是

[0,-1,0] [-1,4,-1] [0,-1,0]

使用python来执行同样的操作,结果是一样的哦!

代码语言:javascript
复制
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('src.jpg') a=[ [0,-1,0], [-1,4,-1], [0,-1,0] ] kernel = np.array(a) dst = cv2.filter2D(img,-1,kernel) cv2.imshow('src',img) cv2.imshow("dst",dst) cv2.waitKey() 

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/140737.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原理:
  • 代码:
  • 结果:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档