CV_tutorial1

news2024/11/25 15:42:57

CV Entry-Level

  • Recurrent Neural Networks
    • 序列数据sequence data
    • 语言模型languag model
    • 循环神经网络recurrent neural networks
    • 门控循环单元gated recurrent unit
    • 长短期记忆网络long short-term memory
  • OpenCV 图形图像操作
      • 文档矫正
      • Gamma变化
      • 开运算
    • 传统图像分割
      • 分水岭算法

Recurrent Neural Networks

序列数据sequence data

前后数据通常具有关联性
比如:语音识别、音乐生成、视频行为识别、机器翻译、DNA序列分析。

语言模型languag model

语言模型是自然语言处理(NLP)的重要技术。NLP中常把文本看作是离散时间序列,一段长度为T的文本的词依次为 w 1 w_1 w1 w 2 w_2 w2、…、 w t w_t wt,其中 w t w_t wt时间步(Time Step)t 的输出或标签。
统计语料库(corpus)中的词频,语言模型将会计算该序列的概率P( w 1 , w 2 , . . . , w t w_1,w_2,...,w_t w1,w2,...,wt)
缺点:时间步t的词需要考虑t-1步的词,计算量随t呈指数增长。

循环神经网络recurrent neural networks

RNN是针对序列数据而生的神经网络结构,核心在于循环使用网络层参数,避免时间步增大带来的参数激增。并且,引入隐藏状态(Hidden State)用于记录历史信息,有效的处理数据的前后关联性。

激活函数为tanh,值域为(-1,1)

RNN的隐藏状态可以捕捉截至当前时间步的序列的历史信息。

但是梯度会随时间t呈指数变化,易引发梯度变化或梯度爆炸。

门控循环单元gated recurrent unit

GRU
缓解RNN梯度消失带来的问题,引入门概念,来控制信息流动,使模型更好记住长远时期的信息,并缓解梯度消失。

重置门 R t R_t Rt:哪些信息需要遗忘
更新门 Z t Z_t Zt:哪些信息需要注意

激活函数为Sigmoid,值域为(0,1),0表示遗忘,1表示保留。

更新门一直保持为1的话,信息可有效传递到当前步。

长短期记忆网络long short-term memory

一种带门控机制的循环神经网络LSTM,

引入3个门和记忆细胞(特殊的隐藏状态,记忆历史信息)
遗忘门:哪些信息需要遗忘
输入门:哪些信息需要流入当前记忆细胞
输出门:哪些记忆信息流入隐藏状态

OpenCV 图形图像操作

环境安装:
python.exe -m pip install --upgrade pip
pip install jupyter
pip install opencv-contrib-python

  • 读入图像
    cv2.imread()
    读取为B-G-R的通道顺序
    使用cv2.cvtColor(src, cv2.COLOR_BGR2RGB)即可转换为RGB顺序图像

  • 通道分离
    cv2.split(img)

  • 添加文字
    cv2.putText()

import numpy as np
import cv2
# 创建一个黑色的背景图
img = np.zeros((512,512,3),np.uint8)

# 添加文字
font = cv2.FONT_HERSHEY_SIMPLEX  # 自带的字体
cv2.putText(img, 'caiman', (20, 200), font, 3, (0,255,0), 5)
# 背景,‘文字内容’,左下角起点坐标,字体,比例(越大越大),颜色,线条粗细

# 创建窗口
winname = 'like'
cv2.namedWindow(winname)

# 显示图像
cv.imshow(winname, img)

# 等待键盘'ESC'命令退出窗口
cv2.waitKey(0)
cv2.destroyWindow(winname)

在这里插入图片描述

文档矫正

放射变换、透视变化

#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
src = cv2.imread('paper.png')

# 获取图像大小
rows, cols = src.shape[:2]

# 将源图像高斯模糊(去噪)
img = cv2.GaussianBlur(src, (3, 3), 0)
# 灰度化(方便边缘检测)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 边缘检测
edges = cv2.Canny(gray, 50, 250, apertureSize = 3)
cv2.imwrite("canny.jpg", edges)
cv2.imshow("canny", edges)

# 通过霍夫变换得到A4纸边缘(点集合)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 50, minLineLength = 90, maxLineGap = 10)
print(lines)
# 下面输出的点为四个顶点
for x1,y1,x2,y2 in lines[0]:
	print(x1,y1)
	print(x2,y2)
for x3,y3,x4,y4 in lines[1]:
	print(x3,y3)
	print(x4,y4)

# 绘制边缘
for x1,y1,x2,y2 in lines[0]:
	cv2.lines(gray, (x1, y1), (x2, y2), (0, 0, 255), 1)

# 根据四个顶点设置图像透视变换矩阵
pos1 = np.float32([[x2,y2], [x4,y4], [x1,y1], [x3,y3]]) 
pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]])
M = cv2.getPerspectiveTransform(pos1, pos2)
print(M)

# 图像透视变换
result = cv2.warpPerspective(src, M, (190, 272))

# 显示图像
cv2.imshow("original", src)
cv2.imshow("result",result)
cv2.imshow("gray",gray)

# 等待显示
cv2.waitKey(0)
cv2.distroyAllWindows()

在这里插入图片描述

Gamma变化

非线性操作
gamma值调整的是图像中的亮度部分,而不会改变过暗或过亮的部分:
当gamma>1时,校正会降低图像亮度,使亮部细节更明显;
当gamma<1时,校正会增加图像亮度,使暗部细节更明显。

import cv2
import numpy as np
img = cv2.imread('img1.png')

def adjust_gamma(image, gamma = 1.0)
	invGamma = 1.0/gamma
	table = []
	for i in range(256):
		table.append(((i / 255.0) ** invGamma) * 255)
	table = np.array(table).astype("uint8")
	print(table)
	return cv2.LUT(image, table)

img_gamma = adjust_gamma(img, 0.8)
cv2.imshow("img", img)
cv2.imshow("img_gamma", img_gamma)

cv2.waitKey(0)
cv2.destoryAllWindows()

在这里插入图片描述

开运算

腐蚀(erode)操作,后膨胀(dilate)操作

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('img.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 设置结构元素的形状和尺寸
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) 

#121:1行2列的第1个图像,122:1行2列的第2个图像
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(openning), plt.title('opening')
plt.xticks([]), plt.yticks([])
plt.show()

对于消除噪音效果很好,
调整结构元素的大小和形状有不同效果。
这是5*5刷子的结果:
在这里插入图片描述

传统图像分割

图像分割是指将图像分成若干具有相似性质的区域的过程

  • 自适应阈值与固定阈值对比
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('img.png', 0) # 默认为1,0作为灰度图读入

# 固定阈值
ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESHOLD_BINARY)
# 自适应阈值(原图,最大阈值、一般为255,小区域阈值的计算方法,阈值方式,小区域面积,最终阈值等于小区域计算出的阈值再减去此值)
th2 = cv2.adaptiveThreshold(
    img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11, 4)
#全局阈值,均值自适应,高斯加权自适应对比
titles = ['Original', 'Global(v = 127)', 'Adaptive Mean(11,4)', 'Adaptive Mean(55,4)', 'Adaptive Gaussian(17,6)', 'Adaptive Gaussian(11,4)']
images = [img, th1, th2, th3, th4, th5]
for i in range(6):
    plt.subplot(3, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i], fontsize=8)
    plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

  • 边缘检测算子
    Canny边缘检测算法:
    • 彩色图像转换为灰度图像
    • 对图像进行高斯模糊(去噪)
    • 计算图像梯度,根据梯度计算图像边缘幅值与角度
    • 沿梯度方向进行非极大值抑制(边缘细化)
    • 双阈值边缘连接处理
    • 二值化图像输出结果
import cv2
import numpy as np
# 以灰度图单通道图读入(彩色图像转换为灰度图像)
img = cv2.imread('lyx.png', 0)
# Canny(源图像,下阈值,上阈值,kernel_size)
v1 = cv2.Canny(img, 80, 200, (3, 3))
v2 = cv2.Canny(img, 50, 100, (5, 5))

# np.vstack():在竖直方向上堆叠
# np.hstack():在水平方向上堆叠
ret = np.hstack((v1, v2)) #拼接这样可以对比来看参数不同的效果不同
cv.imshow('caiman', ret)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

分水岭算法

  1. 加载原始图像
  2. 阈值分割,将图像分割为黑白两个部分
  3. 对图像进行开运算
  4. 对开运算结果再进行膨胀,获取大部分背景区域
  5. 通过距离变换DistanceTransform获取大部分前景区域
  6. 背景区域和前景区域相减abstrac,得到二者重合区域
  7. 连通区域处理
  8. 最后使用分水岭算法
import cv2
import numpy as np
import matplotlib.pyplot as plt

# Step1.加载图像
img = cv2.imread('image/yezi.jpg')
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Step2.固定阈值分割,将图像分为黑白部分
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# Step3.对图像进行‘开运算’(先腐蚀后膨胀)
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

# Step4.对‘开运算’的结果进行膨胀,得到基本就是背景的区域
sure_bg = cv2.dilate(opening, kernel, iterations=3)

# Step5.通过distanceTransform获取基本就是前景的区域sure_fg
# DIST_L1 DIST_C 只能对应掩膜为3, DIST_L2 可以为3或者5
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
print(dist_transform.max())
ret, sure_fg = cv2.threshold(dist_transform, 0.1 * dist_transform.max(), 255,0)

# Step6.sure_bg和sure_fg相减,得到背景和前景的重合区域
# 此区域和轮廓区域的关系位未知
sure_fg = np.uint8(sure_fg)
unknow = cv2.subtract(sure_bg, sure_fg)

# 连通区域处理
ret, markers = cv2.connectedComponents(sure_fg, connectivity=8) # 对连通区域标号,序号为0~N-1
print("原始markers")
print(markers) # markers相当于对前景目标都做了标记
# OpenCV分水岭算法对物体做的标注都必须大于1,背景标号为0,因此需要加1
markers = markers + 1
# 去掉属于背景区域的部分(让其变为0,成为背景)
markers[unknow==255] = 0

# Step8.分水岭算法
markers = cv2.watershed(img, markers) # 分水岭算法后,所有轮廓的像素点被标注为 -1
print("分水岭的markers")
print(markers)
# 标注为-1的像素点标红,OpenCV中颜色通道顺序为BGR
img[markers == -1] = [0, 0, 255]

# *************************打印******************************
titles = ['thresh', 'sure_bg', 'dist_transform', 'sure_fg', 'unknow','dst']
sure_bg2 = cv2.cvtColor(sure_bg, cv2.COLOR_BGR2RGB)
dist_transform2 = cv2.cvtColor(dist_transform, cv2.COLOR_BGR2RGB)
unknow2 = cv2.cvtColor(unknow, cv2.COLOR_BGR2RGB)
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
images = [cv2.cvtColor(thresh, cv2.COLOR_BGR2RGB),sure_bg2, dist_transform2, cv2.cvtColor(sure_fg, cv2.COLOR_BGR2RGB),
          unknow2,img2]
for i in range(6):
    plt.subplot(3, 2, i+1), plt.imshow(images[i],)
    plt.title(titles[i], fontsize = 8)
    plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

145.3628
原始markers
[[0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]]
分水岭的markers
[[-1 -1 -1 ... -1 -1 -1]
 [-1  1  1 ...  1  1 -1]
 [-1  1  1 ...  1  1 -1]
 ...
 [-1  1  1 ...  1  1 -1]
 [-1  1  1 ...  1  1 -1]
 [-1 -1 -1 ... -1 -1 -1]]

处理结果放大:在这里插入图片描述

可以实现像素级别的分割,传统方法的精度要比深度学习方法更高

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

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

相关文章

NX/UG二次开发—建模—文字中心线提取思路简介

一、中心线提取 1、离散文字平面&#xff1a; 离散文字平面&#xff0c;构建一个二维矩阵数组&#xff08;实际操作时用的一维数组&#xff09; 1.1最小边界盒子&#xff1a; 可以计算文字平面的最小边界盒子&#xff0c;然后按步距在平面上采点&#xff0c;优点是点距比较…

【TODO】米哈游20230813笔试第三题

是计算抽中什么当期五星的期望。 现在的程序结果是99.6087。结果不对&#xff0c;有时间再调。 #include <iostream> #include <bits/stdc.h> typedef long long LL; using namespace std;int n 90; double p; // double min_p 1e-7; double min_p 0.0000000000…

根据源码,模拟实现 RabbitMQ - 通过 SQLite + MyBatis 设计数据库(2)

目录 一、数据库设计 1.1、数据库选择 1.2、环境配置 1.3、建库建表接口实现 1.4、封装数据库操作 1.5、针对 DataBaseManager 进行单元测试 一、数据库设计 1.1、数据库选择 MySQL 是我们最熟悉的数据库&#xff0c;但是这里我们选择使用 SQLite&#xff0c;原因如下&am…

什么是多线程?进程和线程的区别是什么?如何使用Java实现多线程?

文章目录 前言我们为什么要使用线程而不是进程来实现并发编程什么是线程进程和线程的区别如何使用Java实现多线程创建线程1.创建一个继承 Thread 类的线程类2.实现 Runnable 接口匿名内部类方式实现 Runnable 接口lambda 表达式实现 Runnable 接口 Thread 类的常见构造方法Thre…

NO.1 MyBatis配置文件:配置连接数据库的环境,实现数据库连接

目录 1、MyBatis配置数据库环境的连接方式 1.1连接方式一&#xff1a;MyBatis核心配置文件配置数据库连接信息 1.2连接方式二&#xff1a;在MyBatis核心配置文件中引入properties文件&#xff0c;配置数据库的环境 2、MyBatisd核心配置文件连接数据库的环境完整配置信息 3…

基于Matlab实现心电信号小波特征提取和对应疾病识别仿真(附上源码+数据集)

本文基于Matlab平台&#xff0c;研究了心电信号的小波特征提取方法&#xff0c;并应用于心电信号疾病识别仿真实验中。首先&#xff0c;介绍了心电信号的基本特征和常见的心电疾病。然后&#xff0c;详细阐述了小波变换的原理和方法&#xff0c;并提出了一种基于小波分解和小波…

[Leetcode] [Tutorial] 多维动态规划(未完待续)

文章目录 62. 不同路径Solution 62. 不同路径 一个机器人位于一个 m ∗ * ∗ n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。 问总共有多少条不同的路径&#xff1f; 示例…

线程转换状态,傻傻分不清等待和阻塞吗?你还在暴力的停止线程吗?

线程切换 线程创建之后&#xff0c;调用start()方法开始运行。当线程执行wait()方法之后&#xff0c;线程进入等待状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态&#xff0c;而超时等待状态相当于在等待状态的基础上增加了超时限制&#xff0c;也就是超…

StringJoiner

1、为什么要学习StringJoiner&#xff1f; 2、StringJoiner概述 StringJoiner跟StringBuilder一样&#xff0c;也可以看成一个容器&#xff0c;创建之后里面的内容是可变的。 2.1、作用 提高字符串的操作效率&#xff0c;而且代码编写特别简洁&#xff0c;但是目前市场上很少有…

用友时空KSOA SQL注入漏洞复现(HW0day)

0x01 产品简介 用友时空KSOA是建立在SOA理念指导下研发的新一代产品&#xff0c;是根据流通企业最前沿的I需求推出的统一的IT基础架构&#xff0c;它可以让流通企业各个时期建立的IT系统之间彼此轻松对话&#xff0c;帮助流通企业保护原有的IT投资&#xff0c;简化IT管理&#…

学习笔记整理-JS-03-表达式和运算符

[[toc]] 一、表达式和运算符 1. 表达式 表达式种类 算术、关系、逻辑、赋值、综合 二、JS基本表达式 1. 算术运算符 意义运算符加减-乘*除/取余% 加减乘除 加减的符号和数学一致&#xff0c;乘号是*号&#xff0c;除法是/号默认情况&#xff0c;乘除法的优先级高于加法和…

【软件工程】软件测试

软件测试的对象 软件程序文档 测试对象&#xff1a;各个阶段产生的源程序和文档。 软件测试的目的 基于不同的立场&#xff0c;对软件测试的目的存在着两种完全对立的观点。 &#xff08;1&#xff09;一种观点是通过测试暴露出软件中所包含的故障和缺陷(从用户的角度)&#xf…

ORB-SLAM2第一节---单目地图初始化

单目初始化 1.前提条件&#xff08;640*480&#xff09; 参与初始化的两帧各自的特征点数目都需要大于100.两帧特征点成功匹配的数目需要大于或等于100.两帧特征点三角化成功的三维点数目需要大于50. 2.针对条件三 流程如下 记录当前帧和参考帧&#xff08;第一帧&#xff…

计算机组成原理 汇编语言

..................................................

fastadmin采坑之页面调转

这里有个业务需求&#xff0c;就是一个表格页面添加一个报名按钮&#xff0c;这个报名按钮就对应另外一个表格页面的新增&#xff0c;那就不用单独写个报名页面了&#xff0c;直接添加一个报名按钮&#xff0c;然后按钮的url直接指向另外一个页面的新增页面&#xff0c;真的很方…

[vscode]vscode运行cmake时候exe不执行而且前面多一些字符

遇到一个奇怪问题,你单独打开cmd去执行vscode编译过程序没问题&#xff0c;但是你在vscode确不会执行&#xff0c;这是因为vscode没有读取到电脑环境变量导致加载DLL失败&#xff0c;但是在vscode终端不会给你提示少DLL&#xff0c;需要你自己把DLL复制到exe目录即可解决问题。…

CDH6.3应知应会

文章目录 1. CDH 简介1.1 CDH版本 2. CDH 集群的优势是什么&#xff1f;3. CDH 集群的部署方式有哪些&#xff1f;4. CDH 集群中如何进行故障排除和监控&#xff1f;5. 你有使用 CDH 部署集群的经验吗&#xff1f;6. CDH 集群如何实现高可用性&#xff1f;7. 在 CDH 集群中&…

Qt Bridge for Adobe Photoshop安装

*社区版没有这个文件夹无法安装&#xff0c;可以下载企业用的&#xff0c;然后给money&#xff0c;不多也就316刀&#xff0c;折合人民币2千多&#xff0c;或者试用10天。 ** B站找到的文章&#xff08;作者&#xff1a;原版英语 https://www.bilibili.com/read/cv17933098 出…

Redis进阶(4)——结合redis.conf配置文件深入理解 Redis两种数据持久化方案:RDB和AOF

目录 引出持久化方案RDBAOF Redis的持久化方案RDB如果采用docker stop关闭如果采用强制关闭 AOF参数设置混编方式的加载让aof进行重写 两种持久化方案的优缺点AOF优缺点RDB优势和劣势 总结 引出 1.Redis数据持久化的两种方式&#xff0c;RDB和AOF; 2.RDB采用二进制存储&#xf…

PHP8的字符串操作1-PHP8知识详解

字符串是php中最重要的数据之一&#xff0c;字符串的操作在PHP编程占有重要的地位。在使用PHP语言开发web项目的过程中&#xff0c;为了实现某些功能&#xff0c;经常需要对某些字符串进行特殊的处理&#xff0c;比如字符串的格式化、字符串的连接与分割、字符串的比较、查找等…