[传统图像处理]-------DOG算子(高斯差分算子)和高斯模糊

2023-10-31

一,DOG算子的作用:

DOG(Difference of Gaussian)意为高斯函数的差分。是灰度图像增强和角点检测的一种方法。

二、高斯模糊

由于DOG是利用高斯模糊(也叫高斯平滑)实现的,所以有必要先讲一下高斯模糊是什么:

对于一个图像而言,如果某个像素点跟一个卷积核进行卷积,如下图的,卷积核的尺寸为3x3,且中心点为1,其余为0,则卷积的前后图像是一样的。原因是当前像素点的值,只跟这一点本身有关(且权重为1),跟周边点无关,所以卷积前后都是一样的。

那么如果卷积核不是这样的呢?是符合高斯分布的呢?

高斯函数我们都看过,就是呈现中间高,四周低的形状(如下图):

在二维的情况下(即图像),二维高斯函数公式如下:

其中σ(sigma)是方差,σ越小高斯函数的峰(中间部分)就越高,σ越大,则峰就越平滑,图像卷积效果也越模糊,更平滑。

所以高斯模糊就是卷积核中的权重跟高斯函数一样,中间高,向四周逐渐趋于平缓。那这样子造成的一个效果就是,当前像素点的值跟四周的值有关系,且越近的点对当前点的贡献就越大,越远的点则贡献越小。所以会起到一个模糊的作用。

高斯模糊代码:

import cv2
import numpy as np
img = cv2.imread('D://fangzi.jpg')
cv2.imshow('img',img)
cv2.resizeWindow('img',640,480)
#img_ = cv2.GaussianBlur(img,ksize=(9,9),sigmaX=0,sigmaY=0)
img_ = cv2.GaussianBlur(img,(9,9),2)
cv2.imshow('img_',img_)
cv2.resizeWindow('img_',640,480)
cv2.waitKey()

效果:

 

三、DOG算子原理:

我们知道高斯模糊后,就开始看看DOG算子了。

DOG是用于角点检测(也叫特征点提取)的。主要流程如下图:

左边是原图和三种不同σ的高斯模糊后的图。右边是对高斯滤波后的图片(相邻状态下)依次进行两两相减可得到右边的三个高斯函数的差分图(简称DOG)。

红色标记为当前像素点,黄色对应的像素点表示当前像素点邻接的点,共26(上图中27个黄点减去一个红点)个,如果该点(红点)是所有邻接像素点(黄点)的最大值或最小值,则红色标记对应的点为特征点。

DOG代码:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
	Mat ori_img = imread("D://lena.png");
	Mat gray_img;
	cvtColor(ori_img, gray_img, CV_RGB2GRAY);
	imshow("gray", gray_img);
	gray_img.convertTo(gray_img, CV_32F);// float -像素是在0-1.0之间的任意值,这对于一些数据集的计算很有用,但是它必须通过将每个像素乘以255来转换成8位来保存或显示。

	Mat gauss1, gauss2;
	GaussianBlur(gray_img, gauss1, Size(5, 5), 0.3, 0.3);
	GaussianBlur(gray_img, gauss2, Size(5, 5), 0.4, 0.4);

	Mat DoG1, DoG2, DoG3;
	DoG1 = gauss1 - gauss2;
	imshow("DOG1", DoG1);
	GaussianBlur(gray_img, gauss1, Size(5, 5), 0.6, 0.6);
	GaussianBlur(gray_img, gauss2, Size(5, 5), 0.7, 0.7);
	DoG2 = gauss1 - gauss2;
	imshow("DOG2", DoG2);
	GaussianBlur(gray_img, gauss1, Size(5, 5), 0.7, 0.7);
	GaussianBlur(gray_img, gauss2, Size(5, 5), 0.8, 0.8);
	DoG3 = gauss1 - gauss2;
	imshow("DOG3", DoG3);
	for (int j = 1; j < gray_img.rows - 1; j++)
	{
		for (int i = 1; i < gray_img.cols - 1; i++)
		{
			if (DoG2.at<float>(j, i) < DoG2.at<float>(j - 1, i - 1) && DoG2.at<float>(j, i) < DoG2.at<float>(j - 1, i) &&
				DoG2.at<float>(j, i) < DoG2.at<float>(j - 1, i + 1) && DoG2.at<float>(j, i) < DoG2.at<float>(j, i - 1) && DoG2.at<float>(j, i) < DoG2.at<float>(j, i + 1) &&
				DoG2.at<float>(j, i) < DoG2.at<float>(j + 1, i - 1) && DoG2.at<float>(j, i) < DoG2.at<float>(j + 1, i) && DoG2.at<float>(j, i) < DoG2.at<float>(j + 1, i + 1)
				&& DoG2.at<float>(j, i) < DoG1.at<float>(j, i) && DoG2.at<float>(j, i) < DoG1.at<float>(j - 1, i - 1) && DoG2.at<float>(j, i) < DoG1.at<float>(j - 1, i) &&
				DoG2.at<float>(j, i) < DoG1.at<float>(j - 1, i + 1) && DoG2.at<float>(j, i) < DoG1.at<float>(j, i - 1) && DoG2.at<float>(j, i) < DoG1.at<float>(j, i + 1) &&
				DoG2.at<float>(j, i) < DoG1.at<float>(j + 1, i - 1) && DoG2.at<float>(j, i) < DoG1.at<float>(j + 1, i) && DoG2.at<float>(j, i) < DoG1.at<float>(j + 1, i + 1)
				&& DoG2.at<float>(j, i) < DoG3.at<float>(j, i) && DoG2.at<float>(j, i) < DoG3.at<float>(j - 1, i - 1) && DoG2.at<float>(j, i) < DoG3.at<float>(j - 1, i) &&
				DoG2.at<float>(j, i) < DoG3.at<float>(j - 1, i + 1) && DoG2.at<float>(j, i) < DoG3.at<float>(j, i - 1) && DoG2.at<float>(j, i) < DoG3.at<float>(j, i + 1) &&
				DoG2.at<float>(j, i) < DoG3.at<float>(j + 1, i - 1) && DoG2.at<float>(j, i) < DoG3.at<float>(j + 1, i) && DoG2.at<float>(j, i) < DoG3.at<float>(j + 1, i + 1))
			{
				//cout << DoG2.at<float>(j, i);
				if (DoG2.at<float>(j, i) < -3)
				{
					circle(ori_img, Point(i, j), 3, CV_RGB(0, 0, 255));
				}
			}
			else
				if (DoG2.at<float>(j, i) > DoG2.at<float>(j - 1, i - 1) && DoG2.at<float>(j, i) > DoG2.at<float>(j - 1, i) &&
					DoG2.at<float>(j, i) > DoG2.at<float>(j - 1, i + 1) && DoG2.at<float>(j, i) > DoG2.at<float>(j, i - 1) && DoG2.at<float>(j, i) > DoG2.at<float>(j, i + 1) &&
					DoG2.at<float>(j, i) > DoG2.at<float>(j + 1, i - 1) && DoG2.at<float>(j, i) > DoG2.at<float>(j + 1, i) && DoG2.at<float>(j, i) > DoG2.at<float>(j + 1, i + 1)
					&& DoG2.at<float>(j, i) > DoG1.at<float>(j, i) && DoG2.at<float>(j, i) > DoG1.at<float>(j - 1, i - 1) && DoG2.at<float>(j, i) > DoG1.at<float>(j - 1, i) &&
					DoG2.at<float>(j, i) > DoG1.at<float>(j - 1, i + 1) && DoG2.at<float>(j, i) > DoG1.at<float>(j, i - 1) && DoG2.at<float>(j, i) > DoG1.at<float>(j, i + 1) &&
					DoG2.at<float>(j, i) > DoG1.at<float>(j + 1, i - 1) && DoG2.at<float>(j, i) > DoG1.at<float>(j + 1, i) && DoG2.at<float>(j, i) > DoG1.at<float>(j + 1, i + 1)
					&& DoG2.at<float>(j, i) > DoG3.at<float>(j, i) && DoG2.at<float>(j, i) > DoG3.at<float>(j - 1, i - 1) && DoG2.at<float>(j, i) > DoG3.at<float>(j - 1, i) &&
					DoG2.at<float>(j, i) > DoG3.at<float>(j - 1, i + 1) && DoG2.at<float>(j, i) > DoG3.at<float>(j, i - 1) && DoG2.at<float>(j, i) > DoG3.at<float>(j, i + 1) &&
					DoG2.at<float>(j, i) > DoG3.at<float>(j + 1, i - 1) && DoG2.at<float>(j, i) > DoG3.at<float>(j + 1, i) && DoG2.at<float>(j, i) > DoG3.at<float>(j + 1, i + 1))
				{
					if (DoG2.at<float>(j, i) > 3)
					{
						circle(ori_img, Point(i, j), 3, CV_RGB(255, 0, 0));
					}
				}
		}
	}
    imshow("result", ori_img);
	waitKey(0);

效果:

输入的灰度图:

dog1:

dog2:

dog3:

result:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[传统图像处理]-------DOG算子(高斯差分算子)和高斯模糊 的相关文章

随机推荐

  • SPI协议代码

    软件模拟SPI程序代码 文章目录 SPI协议简介 SPI接口介绍 SPI数据传输方向 SPI传输模式 通过两个单片机模拟SPI来加深理解 硬件连接方式 SPI模式 程序思路 主机C代码 波形 从机C代码 波形 概述 通过两个MCU STM3
  • Mybatis系列七:映射文件-自定义结果集

    一 案例1
  • 使用Clion进行Qt项目开发

    使用Clion进行Qt项目开发 创建项目并指定Qt CMake prefix path为Qt安装路径下的E Qt Qt5 9 1 5 9 1 mingw53 32 配置编译工具链 添加外部工具 找到Setting gt Tool gt Ex
  • 使用hexo和git实现多地更新和配置博客源文件

    使用hexo写博客的一个问题就是源文件都是在本地的 如果换了电脑需要更新博客时就会比较麻烦 目前 觉得比较靠谱的办法就是用github来管理了 主要的思路是 利用git分支实现 hexo生成的静态博客文件默认放在master分支上 hexo
  • 面向对象程序设计的基本概念

    原文链接 面向对象设计 类和对象 1 面向对象程序设计的基本概念 Java是一种面向对象的编程语言 面向对象编程 英文是Object Oriented Programming 简称OOP 那什么是面向对象编程 面向对象其实是现实世界模型的自
  • 计算机图形学【GAMES-101】1、矩阵变换原理Transform(旋转、位移、缩放、正交投影、透视投影)

    快速跳转 1 矩阵变换原理Transform 旋转 位移 缩放 正交投影 透视投影 2 光栅化 反走样 傅里叶变换 卷积 3 着色计算 深度缓存 着色模型 着色频率 4 纹理映射 重心坐标插值 透视投影矫正 双线性插值MipMap 环境光遮
  • 【从零开始学爬虫】采集京东商品信息

    l 采集网站 场景描述 采集京东电视分类中的所有商品信息 使用工具 前嗅ForeSpider数据采集系统 免费版本下载链接 http www forenose com view forespider view download html 入
  • vlc控制台命令总结

    本机摄像头和麦克风 dshow vdev USB Camera dshow adev 麦克风 USB Microphone 播放本机摄像头 vlc dshow dshow vdev USB Camera dshow adev 麦克风 USB
  • 2023毕业设计-(java)音乐网站播放器+音乐网站管理系统+音乐网站后台(附下载链接)

    音乐网站播放器 点我下载源码和sql文件 介绍 音乐网站播放器 音乐网站管理系统 音乐网站后台 源码 数据库文件 软件架构 使用vue springboot mybatis plus mysql技术的前后端分离项目 前端 安装教程 需要有n
  • Java 网络安全

    1 常见的 Web 攻击 1 1 CSRF攻击 1 1 1 CSRF如何防护 1 2 XSS 攻击 1 2 1 XSS 攻击分类 1 2 2 XSS 防护 1 3 DOS 攻击 1 3 1 防护 1 4 SQL 注入 1 4 1 SQL 注
  • Allegro中走线长度的设置

    PROPAGATION DELAY PROPAGATION DELAY这个设定主要用来对Net绝对长度的设定 如要求设定一组Net的长度要在Min Mil到 Max Mil之间的话 就可以用这种设定来完成 要求走线Net长度在Min与Max
  • 如何去除页面上的空格

    let a this nsrsbh this nsrsbh replace s s g 左边是处理完以后的 let a 也就是a这个变量才是处理过的 结果是 页面上写空格不会再出现报错的情况了
  • 关于php unset的随笔

    我们可能都知道C 在使用了构造函数后再使用析构函数来释放内存 那么PHP需不需要使用unset来进行变量释放内存呢 偶然的 我们遇到 out of memory 的错误 但是服务器内存明明还有很多 memory limit也是得很大 但是就
  • JAVA CPU过高异常处理

    1 首先用 ps aux grep jar包名字 找到进程的PID 直接top命令也能看到CPU最高的进程PID 2 用 top Hp 进程PID 获取CPU占用高的线程 下图中PID的1091 1063就是线程ID 网上的文章用 ps m
  • opengl模拟太阳效果

    参考 http www cnblogs com tkgamegroup p 4198811 html 我决定开个新坑了 以后每周五更新 这是GLSL的学习周记 GLSL就是OPENGL SHADER LANGUAGE的简称 就是着色器语言
  • NLP 利器 Gensim 中 word2vec 模型词嵌入 Word Embeddings 的可视化

    本文为系列文章之一 前面的几篇请点击链接 NLP 利器 gensim 库基本特性介绍和安装方式 NLP 利器 Gensim 库的使用之 Word2Vec 模型案例演示 NLP 利器 Gensim 来训练自己的 word2vec 词向量模型
  • 字符串方法

    字符串方法 slice 字符串截取 第一个参数 开始索引 下标 包括开始 第二个参数 结束索引 下标 不包括结束 截取字符串 var str elephant var rel str slice 0 3 console log rel 截取
  • ArcMap显示XY数据时部分字段未显示的解决办法之曲线救国

    ArcMap显示XY数据时部分字段未显示的解决办法之曲线救国 要解决的问题 问题之所在 曲线救国解决问题 要解决的问题 当我们要把xls xlsx csv等表格数据转换成shp文件的时候 其中有一步是要显示xy数据 如下图 正常情况下里面最
  • latex学习(1)

    1 latex中插入图片 需要调用 usepackage graphicx 和 usepackage float 宏包 begin figure H small centering includegraphics width 13cm he
  • [传统图像处理]-------DOG算子(高斯差分算子)和高斯模糊

    一 DOG算子的作用 DOG Difference of Gaussian 意为高斯函数的差分 是灰度图像增强和角点检测的一种方法 二 高斯模糊 由于DOG是利用高斯模糊 也叫高斯平滑 实现的 所以有必要先讲一下高斯模糊是什么 对于一个图像