opencv笔记2

 图像灰度

彩色图像转化为灰度图像的过程是图像的灰度化处理。彩色图像中的每个像素的颜色由R,G,B三个分量决定,而每个分量中可取值0-255,这样一个像素点可以有256*256*256变化。而灰度图像是R,G,B三个分量相同的一种特殊的彩色图像,其中一个像素点的变化范围为256种。灰度图像的描述与彩色图像一样仍然反映了整副图像的整体和局部的色度和高亮等级的分布和特征。

在OpenCV中,用cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)来实现对图像进行灰度化处理。

import cv2
import rclpy
from rclpy.node import Node
import numpy as np
from ament_index_python.packages import get_package_share_directory #获取shares目录绝对路径

class OpenCVNode(Node):
    def readImg(self,img_name: str):
        default_image_path = get_package_share_directory('yahboom_esp32ai_car')+'/resource/'+img_name
        self.get_logger().info(f'打开图片:{default_image_path}')
        img = cv2.imread(default_image_path)
        self.get_logger().info(f'image shape:{img.shape}')
        #灰度
        gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
  
        cv2.imshow('src',img)
        cv2.imshow('gray',gray)
        cv2.waitKey(0)

def main():
    rclpy.init()
    node = OpenCVNode('opencvNode')
    node.readImg('2.jpg') 
    rclpy.spin(node)
    rclpy.shutdown()

效果

OpenCV图像二值化处理

给定阈值,大于阈值的为0(黑色)或 255(白色),使图像称为黑白图。阈值可固定,也可以自适应阈值。自适应阈值一般为一点像素与这点为中序的区域像素平均值或者高斯分布加权和的比较。

cv2.threshold(src, threshold, maxValue, thresholdType)

参数含义:

src:原图像

threshold:当前阈值

maxVal:最大阈值,一般为255

thresholdType:阈值类型

  • cv.THRESH_BINARY
  • cv.THRESH_BINARY_INV
  • cv.THRESH_TRUNC
  • cv.THRESH_TOZERO
  • cv.THRESH_TOZERO_INV

返回值:

retval:与参数thresh一致

dst: 结果图像

import cv2
import rclpy
from rclpy.node import Node
import numpy as np
from ament_index_python.packages import get_package_share_directory #获取shares目录绝对路径

class OpenCVNode(Node):
    def readImg(self,img_name: str):
        default_image_path = get_package_share_directory('yahboom_esp32ai_car')+'/resource/'+img_name
        self.get_logger().info(f'打开图片:{default_image_path}')
        src = cv2.imread(default_image_path)
      
        #灰度
        img = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
        ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
        ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
        ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
        ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
        ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
        cv2.imshow('gray',img)
        cv2.imshow('BINARY',thresh1)
        cv2.imshow('BINARY_INV',thresh2)
        cv2.imshow('TRUNC',thresh3)
        cv2.imshow('TOZERO',thresh4)
        cv2.imshow('TOZERO_INV',thresh5)
        cv2.waitKey(0)

def main():
    rclpy.init()
    node = OpenCVNode('opencvNode')
    node.readImg('1.jpg') 
    rclpy.spin(node)
    rclpy.shutdown()

效果如下

图像边缘检测

边缘检测是识别出图像中亮度变化剧烈的像素点构成的集合。图像边缘的正确检测对于分析图像中的内容、实现图像中物体的分割、定位等具有重要的作用。边缘检测大大减少了源图像的数据量,显著减少图像的数据规模。主要是从数学角度去分类,简单了解下背景:如果将图像的每一行像素和每一列像素都描述成一个关于灰度值的函数,函数值的变化趋势可以用函数的导数描述,图像的边缘对应在灰度值函数中是函数值突然变大的区域,进而确定图像中的边缘位置。

分类如下:

一阶导数的边缘检测算子:通过计算图像的梯度值来检测图像的边缘,常见的有Roberts算子、Sobel算子和Prewitt算子。

二阶导数的边缘算子:通过寻求二阶导数中的过零点来检测边缘,,常见的有Laplacian 算子,此类算子对噪声敏感。

其他边缘算子:前面两类均是通过微分算子来检测图像边缘,还有一种就是Canny算子,其是在满足一定约束条件下推导出来的边缘检测最优化算子。

目前有多种算法可以进行边缘检测,虽然Canny算法年代久远,但可以说它是边缘检测的一种标准算法,而且仍在研究中广泛使用。

Canny算子的简要步骤如下:

(1)去噪声:应用高斯滤波来平滑图像,目的是去除噪声

(2)梯度:找寻图像的梯度

(3)非极大值抑制:应用非最大抑制技术来过滤掉非边缘像素,将模糊的边界变得清晰。该过程保留了每个像素点上梯度强度的极大值,过滤掉其他的值。

(4)应用双阈值的方法来区分强边缘和弱边缘

(5)利用滞后技术来跟踪边界。若某一像素位置和强边界相连的弱边界认为是边界,其他的弱边界则被删除。

背后有很多数学推导过程,网上很多大佬写文章介绍,还有很多深度展开调整参数的。
https://blog.csdn.net/zaishuiyifangxym/article/details/90142702

https://zhuanlan.zhihu.com/p/447565904

https://zhuanlan.zhihu.com/p/99959996

看下OpenCV里面,canny算法的实现步骤

.Canny方法处理得到图像:edges=cv2.Canny( image, threshold1, threshold2[, apertureSize[, L2gradient]])

参数含义:

edges:计算得到的边缘图像

image :计算得到的边缘图像,一般是高斯处理后得到的图像

threshold1 :处理过程中的第一个阈值

threshold2 :处理过程中的第二个阈值

apertureSize :Sobel 算子的孔径大小

import cv2
import rclpy
from rclpy.node import Node
import numpy as np
from ament_index_python.packages import get_package_share_directory #获取shares目录绝对路径

class OpenCVNode(Node):
    def readImg(self,img_name: str):
        default_image_path = get_package_share_directory('yahboom_esp32ai_car')+'/resource/'+img_name
        self.get_logger().info(f'打开图片:{default_image_path}')
        img = cv2.imread(default_image_path)
      
        #灰度
        gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        #高斯降噪
        gaussian = cv2.GaussianBlur(gray, (5, 5), 0)
        # Canny算子
        Canny50 = cv2.Canny(gaussian, 50, 50)
        Canny100 = cv2.Canny(gaussian, 50, 100)
        Canny150 = cv2.Canny(gaussian, 50, 150)
        #
        cv2.imshow('gray',gray)
        cv2.imshow('Canny50',Canny50)
        cv2.imshow('Canny100',Canny100)
        cv2.imshow('Canny150',Canny150)
        cv2.waitKey(0)

def main():
    rclpy.init()
    node = OpenCVNode('opencvNode')
    node.readImg('e.jpg') 
    rclpy.spin(node)
    rclpy.shutdown()

通过调整canny参数,可见效果不同,第二个阈值越大,图片丢失细节越多。

OpenCV绘制图形

划线

cv2.line(dst,pt1,pt2,color,thickness=None,lineType=None,shift=None)函数进行线段的绘制。

参数含义:

dst:输出图像。

pt1,pt2:必选参数。线段的坐标点,分别表示起始点和终止点

color:必选参数。用于设置线段的颜色

thickness:可选参数。用于设置线段的宽度

lineType:可选参数。用于设置线段的类型,可选8(8邻接连接线-默认)、4(4邻接连接线)和cv2.LINE_AA 为抗锯齿

画矩形

cv2.rectangle(img,pt1,pt2,color,thickness=None,lineType=None,shift=None)

参数含义:

img:画布或者载体图像

pt1,pt2:必选参数。矩形的顶点,分别表示顶点与对角顶点,即矩形的左上角与右下角(这两个顶点可以确定一个唯一的矩形),可以理解成是对角线。

color:必选参数。用于设置矩形的颜色

 

画圆

cv2.circle(img, center, radius, color[,thickness[,lineType]])

参数含义:

img:画或者载体图像布

center:为圆心坐标,格式: (50,50)

radius:半径

thickness: 线条粗细。默认为1.如果-1则为填充实心

lineType:线条类型。

画椭圆

cv2.ellipse(img, center, axes, angle, StartAngle, endAngle, color[,thickness[,lineType]

参数含义:

center:椭圆的中心点,(x,y)

axes:指的是短半径和长半径,(x,y)

StartAngle:圆弧起始角的角度

endAngle:圆弧终结角的角度

画多边形

cv2.polylines(img,[pts],isClosed, color[,thickness[,lineType]])

参数含义:

pts:多边形的顶点

isClosed:是否闭合。(True/False)

文字

cv2.putText(img, str, origin, font, size,color,thickness)

参数含义:

img:输入图像

str:绘制的文字

origin:左上角坐标(整数),可以理解成文字是从哪里开始的

font:字体

size:字体大小

color:字体颜色

thickness:字体粗细

import cv2
import rclpy
from rclpy.node import Node
import numpy as np
from ament_index_python.packages import get_package_share_directory #获取shares目录绝对路径

class OpenCVNode(Node):
    def readImg(self,img_name: str):
        default_image_path = get_package_share_directory('yahboom_esp32ai_car')+'/resource/'+img_name
        self.get_logger().info(f'打开图片:{default_image_path}')
        img = cv2.imread(default_image_path)
      
        #划线
        line = cv2.line(img, (50,20), (20,100), (255,0,255), 10)
      
        #画矩形
        rect = cv2.rectangle(img, (110,50), (200,200), (255,0,255), 10)
        #画圆
        circle = cv2.circle(img, (280,120), 50, (255,0,255), 10)
        #画椭圆
        ellipse = cv2.ellipse(img, (400,120), (20,50),0,0, 360,(255,0,255), 5)
        # text
        cv2.putText(img,'bohu text test',(50,550),cv2.FONT_HERSHEY_SIMPLEX,1,(0,200,0),2)
        #多边形
        points = np.array([[120,250], [340,440], [350,410], [250,250]], np.int32)
        cv2.polylines(img, [points],True,(255,0,255), 5)

        cv2.imshow('gray',img)
   
        cv2.waitKey(0)

def main():
    rclpy.init()
    node = OpenCVNode('opencvNode')
    node.readImg('e.jpg') 
    rclpy.spin(node)
    rclpy.shutdown()

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Hadoop•用Web UI查看Hadoop状态词频统计

听说这里是目录哦 通过Web UI查看Hadoop运行状态🐇一、关闭防火墙二、在物理计算机添加集群的IP映射三、启动集群四、进入HDFS的Web UI 词频统计🦩1、准备文本数据2、在HDFS创建目录3、上传文件4、查看文件是否上传成功5、运行MapReduce程序6、查看MapRe…

C语言二级查漏补缺

直接拿错过的选择开始补知识点 二叉树 推荐视频 基础名词讲解 根节点(Root):二叉树的顶端节点,没有父节点。子节点(Children):每个节点下面的节点。对于二叉树来说,每个节点最多…

Low-Level 大一统:如何使用Diffusion Models完成视频超分、去雨、去雾、降噪等所有Low-Level 任务?

Diffusion Models专栏文章汇总:入门与实战 前言:视频在传输过程中常常因为各种因素(如恶劣天气、噪声、压缩和传感器分辨率限制)而出现质量下降,这会严重影响计算机视觉任务(如目标检测和视频监控)的性能。现有的视频修复方法虽然取得了一些进展,但通常只能针对特定的退…

【22】Word:小李-高新技术企业政策❗

目录 题目​ NO1.2 NO3 NO4 NO5.6 NO7.8 NO9.10 若文章中存在删除空白行等要求,可以到最后来完成。注意最后一定要检查此部分!注意:大多是和事例一样即可,不用一摸一样,但也不要差太多。 题目 NO1.2 F12Fn&a…

【前端】CSS学习笔记(1)

目录 CSS的简介CSS的概念语法 CSS的引入方式内联样式(行内样式)内部样式外部样式(推荐) 选择器全局选择器元素选择器类选择器ID选择器合并选择器后代选择器子选择器相邻兄弟选择器通用兄弟选择器伪类选择器:link:visited:hover:ac…

C#与AI的共同发展

C#与人工智能(AI)的共同发展反映了编程语言随着技术进步而演变,以适应新的挑战和需要。自2000年微软推出C#以来,这门语言经历了多次迭代,不仅成为了.NET平台的主要编程语言之一,还逐渐成为构建各种类型应用程序的强大工具。随着时…

几何数据结构之四叉树与八叉树

几何数据结构之四叉树与八叉树 四叉树的定义四叉树深度的计算公式推导假设:计算过程:1. 划分空间:2. 节点容纳的最小距离:3. 解出深度:4. 考虑常数项: 总结: 八叉树 四叉树的定义 四叉树&#…

机器学习中的方差与偏差

文章目录 方差与偏差1.1 数据1.1.1 数据的分布1.1.2 拟合 1.2 方差与偏差1.2.1 泛化误差的拆分1.2.2 理解方差偏差 1.3 方差-偏差trade-off1.3.1 方差-偏差trade-off1.3.2 方差与偏差诊断 1.4 降低策略1.4.1 噪声1.4.2 高偏差1.4.3 高方差 方差与偏差 1.1 数据 1.1.1 数据的分…

Weblogic - General - 弱口令 任意文件读取漏洞

0x01:漏洞简介 首先需要说明,本文并不是介绍了 Weblogic 某一 CVE 漏洞,而是提供了一种通用的测试思路。 0x0101:弱口令漏洞 弱口令漏洞主要是由于用户安全意识淡薄,为了便于记忆,设置了强度过低的密码&…

C#中的语句

C#提供了各式各样的语句,大多数是由C和C发展而来,当然,在C#中做了相应修改。语句和表达式一样,都是C#程序的基本组成部分,在本文我们来一起学习C#语句。 1.语句 语句是构造所有C#程序的过程构造块。在语句中可以声明…

VLAN基础理论

VLAN V:Virtual(虚拟) LAN ——局域网 VLAN ——虚拟局域网(虚拟广播域:交换机和路由器协同工作后,将原来的一个广播域,逻辑上切分为多个。) VLAN的配置我们基于以下拓扑进行: PC1-4的IP地址依次为192.168.1.1-192.168…

基于SpringBoot的健身房管理系统【源码+文档+部署讲解】

系统介绍 基于SpringBootVue实现的健身房管理系统采用前后端分离架构方式,系统设计了管理员、会员、员工三种角色,系统实现了用户登录与注册、个人中心、会员管理、员工管理、会员卡管理、会员卡类型管理、教练信息管理、解聘管理、健身项目管理、指导项…

C++ 模拟真人鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…

搭建一个基于Spring Boot的校园台球厅人员与设备管理系统

搭建一个基于Spring Boot的校园台球厅人员与设备管理系统可以涵盖多个功能模块,例如用户管理、设备管理、预约管理、计费管理等。以下是一个简化的步骤指南,帮助你快速搭建一个基础的系统。 — 1. 项目初始化 使用 Spring Initializr 生成一个Spring …

Langchain+FastApi+Vue前后端Ai对话(超详细)

一、引入 首先可以先看下作者的文章 FastApi相关文章:创建最简单FastApi的项目Vue相关文章:最简单的aixos二次封装Langchain相关文章:如何使用LangSmith跟踪deepseek模型 二、后端搭建 1 项目文件结构 routers:存放api接口se…

图像去雾数据集的下载和预处理操作

前言 目前,因为要做对比实验,收集了一下去雾数据集,并且建立了一个数据集的预处理工程。 这是以前我写的一个小仓库,我决定还是把它用起来,下面将展示下载的路径和数据处理的方法。 下面的代码均可以在此找到。Auo…

Java中json的一点理解

一、Java中json字符串与json对象 1、json本质 json是一种数据交换格式。 常说的json格式的字符串 > 发送和接收时都只是一个字符串,它遵循json这种格式。 2、前后端交互传输的json是什么? 前后端交互传输的json都是json字符串 比如:…

React实现拖拽特效

前言 最近,我看到一个工程师的个人网站上,采用了拖拽作品集的互动特效,既有趣又吸引眼球。经过一些研究,我发现其实借助一些现成的套件,就能轻松实现这样的效果。今天就带大家一起看看,如何通过 Framer Mo…

leetcode904-水果成篮

leetcode 904 时间复杂度:O(n) 空间复杂度:O(1) 之前发布了一个滑动窗口的题目解答思路,参考博文:长度最小的子数组 本题也是基于滑动窗口的一个扩展题,主要解决方法是利用滑动窗口哈希表 var totalFruit function…

线性代数概述

矩阵与线性代数的关系 矩阵是线性代数的研究对象之一: 矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,是线性代数中的核心概念之一。矩阵的定义和性质构成了线性代数中矩阵理论的基础,而矩阵运算则简洁地表示和…