C++PythonC# 三语言OpenCV从零开发(8):图像平滑处理

文章目录

  • 相关链接
  • 前言
  • 图像资源
  • 图像平滑处理
  • 图像学知识补充(重点)
    • 什么是卷积
    • 什么是图像滤波
    • 什么是方框滤波和均值滤波
  • 代码
    • Python
    • C++
    • Csharp
  • 总结

相关链接

C++&Python&Csharp in OpenCV 专栏

【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程(附带课程课件资料+课件笔记)

前言

这次来了解一下图像平滑处理。还是老套路,先写Python,再C++,再Csharp。本篇文章难的不是代码,难的是图像学的知识

图像资源

为什么Lena的那张图会成为数字图像处理的标准图?

在这里插入图片描述

图像平滑处理

图像平滑处理就是PS中常用的模糊工具,涂抹工具。算法怎么计算的可以看这个文章

数字图像处理之均值滤波

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

图像学知识补充(重点)

本章的难点就是图形学的知识了。这里推荐一本书【数字图像处理(中译第三版)[冈萨雷斯]】
在这里插入图片描述

目录简单展示
在这里插入图片描述

什么是卷积

卷积是一种叠加态的问题的解法。叠加态的问题有:

  • 水池有两个水龙头,一个放水一个抽水。
  • 人一天的体重变化,早餐还没彻底消化完,就吃午餐了
  • 冰箱里面的食物整体的新鲜度。不新鲜的会被拿走,新鲜的食材会被放进来
  • 湖泊的水位,下雨天水位上升,不下雨水位慢慢下降

这个就是卷积的特点:叠加状态。

那么图像的卷积是什么意思?就是考虑到每个像素对应周围像素的影响,卷积后的图像是卷积前的图像像素叠加卷积的结果。通俗点来说,就是黑色像素点周围黑一点,自己白一点。白色像素点周围白一点,自己黑一点。

就像你用墨水写字,然后用水浇上去,字就糊了。这个过程就是卷积。

如何通俗易懂地解释卷积?

瞬时行为的持续性后果,用吃冰淇淋来理解卷积

什么是图像滤波

图标滤波就是对图像的噪点进行抑制,尽量不影响图像的信息量。如果不了解这两个概念,可以近似的看成。

  • 卷积是方法论,是公式
  • 图像滤波是具体实现。

数字图像处理——图像滤波概念及方法

什么是方框滤波和均值滤波

我感觉两个差不多。

十分钟带你了解均值滤波和方框滤波

代码

Python

# %%import cv2
import matplotlib.pyplot as plt
import numpy as npimage_src = cv2.imread('d:\workSpace\OpenCV\HellOpenCV\Resources\images\lena.png')image_config = (7,7)
# 均值滤波
# 最简单的卷积操作
image_blur = cv2.blur(image_src,image_config)# 方框滤波,基本和均值一样
image_box_t = cv2.boxFilter(image_src,-1,image_config,normalize=True)
# 方框滤波,反方向
image_box_f = cv2.boxFilter(image_src,-1,image_config,normalize=False)# 高斯滤波,更重视中间值
image_gaussian = cv2.GaussianBlur(image_src,image_config,1)image_median = cv2.medianBlur(image_src,7)# 因为openCV默认BGR,Plt默认RGB,所以要转化一下
# 因为有Csharp的习惯,我习惯默认大写驼峰
def PltImshowRgb(row:int,col:int,index:int,image:np.mat,title:str):plt.subplot(row,col,index)plt.imshow(cv2.cvtColor(image,cv2.COLOR_BGR2RGB))plt.title(title)PltImshowRgb(2,3,1,image_src,'image_src')
PltImshowRgb(2,3,2,image_blur,'image_blur')
PltImshowRgb(2,3,3,image_box_t,'image_box_t')
PltImshowRgb(2,3,4,image_box_f,'image_box_f')
PltImshowRgb(2,3,5,image_gaussian,'image_gaussian')
PltImshowRgb(2,3,6,image_median,'image_median')plt.show()

在这里插入图片描述

用下来的感觉,滤波的效果确实差不多。

想详细了解其中的区别,可以看这篇文章。我就不展开说明了。

数字图像处理(11): 图像平滑 (均值滤波、中值滤波和高斯滤波)

C++

C++我自己写了一个图像合并显示的代码


#include <opencv2/opencv.hpp>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/imgproc.hpp>  
#include<iostream>  
#include <vector>
using namespace std;
using namespace cv;vector<Mat> imageVector;/// <summary>
/// 将图案并排显示
/// </summary>
/// <param name="imgVector"></param>
/// <param name="dst"></param>
/// <param name="imgCols"></param>
void multipleImage(vector<Mat> imgVector, Mat& dst, int imgCols)
{const int MAX_PIXEL = 300;int imgNum = imgVector.size();//选择图片最大的一边 将最大的边按比例变为300像素Size imgOriSize = imgVector[0].size();int imgMaxPixel = max(imgOriSize.height, imgOriSize.width);//获取最大像素变为MAX_PIXEL的比例因子double prop = imgMaxPixel < MAX_PIXEL ? (double)imgMaxPixel / MAX_PIXEL : MAX_PIXEL / (double)imgMaxPixel;Size imgStdSize(imgOriSize.width * prop, imgOriSize.height * prop); //窗口显示的标准图像的SizeMat imgStd; //标准图片Point2i location(0, 0); //坐标点(从0,0开始)//构建窗口大小 通道与imageVector[0]的通道一样Mat imgWindow(imgStdSize.height * ((imgNum - 1) / imgCols + 1), imgStdSize.width * imgCols, imgVector[0].type());for (int i = 0; i < imgNum; i++){location.x = (i % imgCols) * imgStdSize.width;location.y = (i / imgCols) * imgStdSize.height;resize(imgVector[i], imgStd, imgStdSize, prop, prop, INTER_LINEAR); //设置为标准大小//imgWindow()imgStd.copyTo(imgWindow(Rect(location, imgStdSize)));}dst = imgWindow;
}int main()
{auto image = imread("D:/workSpace/OpenCV/HellOpenCV/Resources/images/lena.png");Mat showImage;Mat image_blur;Mat image_box_t;Mat image_box_f;Mat image_gaussian;Mat image_median;Size image_config = Size(7, 7);blur(image, image_blur, image_config);boxFilter(image, image_box_t, -1, image_config,Point(-1,-1),true);boxFilter(image, image_box_f,-1, image_config, Point(-1, -1), false);GaussianBlur(image, image_gaussian, image_config, 1);medianBlur(image, image_median, 7);vector<Mat> images{image,image_blur,image_box_t,image_box_f,image_gaussian,image_median};multipleImage(images, showImage, 3);imshow("C++", showImage);waitKey(0);destroyAllWindows();return 0;
}

在这里插入图片描述

Csharp

还是那句话。C++写好了,Csharp也能写。

internal class Program
{static void Main(string[] args){Mat image = Cv2.ImRead("D:/workSpace/OpenCV/HellOpenCV/Resources/images/lena.png");Mat image_blur = new Mat();Mat image_box_t = new Mat();Mat image_box_f = new Mat();Mat image_gaussian = new Mat();Mat image_median = new Mat();Size image_config = new Size(7,7);Cv2.Blur(image, image_blur, image_config);Cv2.BoxFilter(image, image_box_t, -1, image_config, new Point(-1, -1), true);Cv2.BoxFilter(image, image_box_f, -1, image_config, new Point(-1, -1), false);Cv2.GaussianBlur(image, image_gaussian, image_config, 1);Cv2.MedianBlur(image, image_median, 3);var res = MyOpenCV_Extensions.MultipleImage(new List<Mat>() { image,image_blur,image_box_t,image_box_f,image_gaussian,image_median}, 3);Cv2.ImShow("Csharp", res);Cv2.WaitKey(0);Cv2.DestroyAllWindows();}}

MyOpenCV_Extensions.cs

 public static class MyOpenCV_Extensions{/// <summary>/// 3通道遍历/// </summary>/// <param name="mat"></param>/// <returns></returns>public static int[,,] MatToArray(Mat mat){var res = new int[mat.Rows, mat.Cols, mat.Channels()];for (var i = 0; i < mat.Rows; i++){for (var j = 0; j < mat.Cols; j++){var temp = mat.At<Vec3b>(i, j);res[i, j, 0] = temp[0];res[i, j, 1] = temp[1];res[i, j, 2] = temp[2];}}return res;}public static Mat MultipleImage(List<Mat> lists, int imgCols){const int MAX_PIXEL = 300;int imgNum = lists.Count;//选择图片最大的一边 将最大的边按比例变为300像素Size imgOriSize = lists[0].Size();int imgMaxPixel = Math.Max(imgOriSize.Height, imgOriSize.Width);//获取最大像素变为MAX_PIXEL的比例因子double prop = imgMaxPixel < MAX_PIXEL ? (double)imgMaxPixel / MAX_PIXEL : MAX_PIXEL / (double)imgMaxPixel;Size imgStdSize= new Size(imgOriSize.Width* prop, imgOriSize.Height* prop); //窗口显示的标准图像的SizeMat imgStd = new Mat(); //标准图片Point location = new Point(0, 0); //坐标点(从0,0开始)//构建窗口大小 通道与imageVector[0]的通道一样Mat imgWindow = new Mat(imgStdSize.Height* ((imgNum -1) / imgCols + 1), imgStdSize.Width* imgCols, lists[0].Type());for (int i = 0; i < imgNum; i++){location.X = (i % imgCols) * imgStdSize.Width;location.Y = (i / imgCols) * imgStdSize.Height;Cv2.Resize(lists[i], imgStd, imgStdSize, prop, prop, InterpolationFlags.Linear); //设置为标准大小imgStd.CopyTo(new Mat(imgWindow, new Rect(location, imgStdSize)) ); }return imgWindow;}}

在这里插入图片描述

总结

学这个还是挺无聊的,因为刚开始就是学一些算子的使用。而且用于OpenCV没有Halcon那种进一步的封装,所以代码写起来还是挺痛苦的。最近的学习速度也有点慢下来了。最近在尽力坚持学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2780326.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

第三节 zookeeper基础应用与实战2

目录 1. Watch事件监听 1.1 一次性监听方式&#xff1a;Watcher 1.2 Curator事件监听机制 2. 事务&异步操作演示 2.1 事务演示 2.2 异步操作 3. Zookeeper权限控制 3.1 zk权限控制介绍 3.2 Scheme 权限模式 3.3 ID 授权对象 3.4 Permission权限类型 3.5 在控制台…

【大数据】Flink on Kubernetes 原理剖析

Flink on Kubernetes 原理剖析 1.基本概念2.架构图3.核心概念4.架构5.JobManager6.TaskManager7.交互8.实践8.1 Session Cluster8.2 Job Cluster 9.问题解答 Kubernetes 是 Google 开源的 容器集群管理系统&#xff0c;其提供应用部署、维护、扩展机制等功能&#xff0c;利用 K…

fast.ai 机器学习笔记(三)

机器学习 1&#xff1a;第 8 课 原文&#xff1a;medium.com/hiromi_suenaga/machine-learning-1-lesson-8-fa1a87064a53 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 来自机器学习课程的个人笔记。随着我继续复习课程以“真正”理解它&#xff0c;这些笔记将继续更…

leetcode——滑动窗口题目汇总

本章总结一下滑动窗口的解题思路&#xff1a; 在字符串中使用双指针 left 和 right 围成的一个左闭右开的区域作为一个窗口。不断将 right 向右滑动&#xff0c;直到窗口中的字符串符合条件。此时将 left 向右滑动&#xff0c;直到窗口中的字符串不符合条件&#xff0c;期间需…

【转载】原生社区交友婚恋视频即时通讯双端APP源码 ONE兔2.0版

原生社区交友婚恋视频即时通讯双端APP源码下载ONE兔2.0版 包含后端、H5源码源码&#xff0c;Android源码&#xff0c;IOS源码

麒麟操作系统选型适配:经验与策略分享

一、麒麟操作系统概况 麒麟V10是一款商业版本服务器操作系统&#xff0c;其作为承载业务系统的基础底座&#xff0c;能满足大部分企业的产品需求&#xff0c;各类软硬件适配也都较好。麒麟V10的SP1/SP2/SP3版本内核都是基于OpenEuler 20.03 LTS研发的&#xff0c;其支持X86、A…

Oracle的学习心得和知识总结(三十二)|Oracle数据库数据库回放功能之论文四翻译及学习

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《Oracle Database SQL Language Reference》 2、参考书籍&#xff1a;《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…

【洛谷题解】P1029[普及组]最大公约数和最小公倍数问题

题目链接&#xff1a;[NOIP2001 普及组] 最大公约数和最小公倍数问题 - 洛谷 题目难度&#xff1a;普及- 涉及知识点&#xff1a;stl函数&#xff0c;最大公因数&#xff0c;最小公倍数 题意&#xff1a; 输入输出样例&#xff1a; 分析&#xff1a;直接套用公式优化累加即…

UI自动刷新大法:DataBinding数据绑定

之前我们讲了DataBinding在Activity、Fragment、RecyclerView中的基础使用&#xff0c;而那些常规使用方法里&#xff0c;每当绑定的变量发生数据变化时&#xff0c;都需要ViewDataBinding重新设值才会刷新对应UI。而DataBinding通过内部实现的观察者模式来进行自动刷新UI&…

第六篇【传奇开心果系列】Vant of Vue 开发移动应用示例:深度解析响应式布局支持

传奇开心果系列 系列博文目录Vant开发移动应用示例系列 博文目录前言一、Vant响应式布局介绍二、媒体查询实现响应式布局示例代码三、短点设置实现响应式布局示例代码四、响应式工具类实现响应式布局示例代码五、栅格系统实现响应式布局示例代码六、响应式组件实现响应式布局示…

软件测试风险管理

1 软件测试风险管理 软件测试风险管理是识别、评估和控制测试过程中可能出现的风险&#xff0c;以确保测试活动能够按计划进行并达到预期目标的过程。软件测试风险管理是软件测试过程中的一个关键组成部分&#xff0c;它涉及到识别、评估和控制可能影响软件测试项目成功的不确…

图解密码技术——第六章 混合密码系统

一、混合密码系统 1.介绍 混合密码系统将对称密码和公钥密码的优势结合在一起。使用对称密码对信息进行加密&#xff0c;使用公钥密码对加密信息的对称密码的秘钥进行加密。这样&#xff0c;解决了对称密码的密钥配送问题&#xff0c;由于秘钥较短&#xff0c;所以公钥密码处…

【前端web入门第五天】03 清除默认样式与外边距问题【附综合案例产品卡片与新闻列表】

文章目录: 1.清除默认样式 1.1清除内外边距1.2清除列表圆点(项目符号) 3.外边距问题-合并现象4.外边距问题–塌陷问题5.行内元素垂直内外边距6.圆角与盒子阴影 6.1圆角 6.2 盒子模型-阴影(拓展) 综合案例一 产品卡片 综合案例二 新闻列表 1.清除默认样式 在实际设计开发中,要…

寒假9-蓝桥杯训练

//轨道炮 #include<iostream> using namespace std; #include<algorithm> int logs[100010]; int main() {int n;cin >> n;for (int i 1;i < n;i){cin >> logs[i];}sort(logs 1, logs n 1);int ans 1000000000;for (int i 2;i < n;i){if (…

【Jenkins】Jenkins关闭Jenkins关闭、重启

目录 一、Jenkins关闭、重启 二、Jenkins服务的启动、停止方法。 一、Jenkins关闭、重启 1.关闭Jenkins 只需要在访问jenkins服务器的网址url地址后加上exit&#xff0c;关闭Jenkins服务。 例如&#xff1a;http://localhost:8081/exit 2.重启Jenkies 只有在Jenkins服务启动…

Matplotlib初探:认识数据可视化与Matplotlib

Matplotlib初探&#xff1a;认识数据可视化与Matplotlib Fig.1 利用Matplotlib进行数据可视化( 可视化代码见文末) &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;一、数据可视化简介&#x1f333;&#x1f333;二、Matplotlib库简介&#x…

为什么说 2023 年是 AI 视频生成的突破年?2024 年的 AI 视频生成有哪些值得期待的地方?

Diffusion Models视频生成-博客汇总 前言&#xff1a;2023年是 AI 视频生成的突破年&#xff0c;AI视频已经达到GPT-2级别了。去年我们取得了长足的进步&#xff0c;但距离普通消费者每天使用这些产品还有很长的路要走。视频的“ChatGPT时刻”何时到来&#xff1f; 目录 前言 …

小程序-上传图片功能

技术前置&#xff1a; 1.框架采用colorUI 2.原生开发 功能&#xff1a; 上传图片 1.上传已经拍摄的图片 2.实时拍摄上传 3.设置上传图片数量&#xff0c;每次上传数量 4.上传等待 ChooseImage() {if(this.data.imgList.length>4){_this.ErrorEvent("最多上传4…

网络安全检查表

《网络攻击检查表》 1.应用安全漏洞 2.弱口令&#xff0c;默认口令 3.服务器互联网暴露 4.操作系统&#xff0c;中间件安全漏洞 5.研发服务器&#xff0c;邮件服务器等安全检查

Linux中FIFO管道

介绍&#xff1a; FIFO被称为命名管道&#xff0c;pipe只能用于有血缘关系的进程间通信&#xff0c;但通过FIFO&#xff0c;不相关的进程也可以进程间通信。 FIFO是linux基础文件类型的一种&#xff08;文件类型为p&#xff09;&#xff0c;FIFO文件在磁盘上没有数据块&#…