python-opencv 形态学
五、形态学运算 检测边和 角点
形态学算子检测图像中的边缘和拐角(实际用:Canny或Harris等算法)
5.1 检测边缘
形态学检测边缘的原理:在膨胀时,图像中的物体会想周围“扩张”;腐蚀时,图像中的物体会“收缩”。由于这两幅图像其变化的区域只发生在边缘。所以这时将两幅图像相减,得到的就是图像中物体的边缘。
import cv2
original_img = cv2.imread('image/1.jpg',0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
dilate_img = cv2.dilate(original_img, kernel)
erode_img = cv2.erode(original_img, kernel)
"""
我选了一张较好的图片,有的图片要去噪(高斯模糊)
将两幅图像相减获得边;cv2.absdiff参数:(膨胀后的图像,腐蚀后的图像)
上面得到的结果是灰度图,将其二值化以便观察结果
反色,对二值图每个像素取反
"""
absdiff_img = cv2.absdiff(dilate_img,erode_img);
retval, threshold_img = cv2.threshold(absdiff_img, 40, 255, cv2.THRESH_BINARY);
result = cv2.bitwise_not(threshold_img);
cv2.imshow("rlufei",original_img)
cv2.imshow("dilate_img",dilate_img)
cv2.imshow("erode_img",erode_img)
cv2.imshow("absdiff_img",absdiff_img)
cv2.imshow("threshold_img",threshold_img)
cv2.imshow("result",result)
cv2.waitKey(0)
cv2.destroyAllWindows()
5.2检测拐角
拐角的检测的原理:先用十字形的结构元素膨胀像素,这种情况下只会在边缘处“扩张”,角点不发生变化。接着用菱形的结构元素腐蚀原图像,导致只有在拐角处才会“收缩”,而直线边缘都未发生变化。第二步是用X形膨胀原图像,角点膨胀的比边要多。这样第二次用方块腐蚀时,角点恢复原状,而边要腐蚀的更多。所以当两幅图像相减时,只保留了拐角处。
import cv2
image = cv2.imread('image/1.jpg',0)
original_image = image.copy()
#构造5×5的结构元素,分别为十字形、菱形、方形和X型
cross = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
diamond = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))
diamond[0, 0] = 0
diamond[0, 1] = 0
diamond[1, 0] = 0
diamond[4, 4] = 0
diamond[4, 3] = 0
diamond[3, 4] = 0
diamond[4, 0] = 0
diamond[4, 1] = 0
diamond[3, 0] = 0
diamond[0, 3] = 0
diamond[0, 4] = 0
diamond[1, 4] = 0
square = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5)) #构造方形结构元素
x = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
dilate_cross_img = cv2.dilate(image,cross) #使用cross膨胀图像
erode_diamond_img = cv2.erode(dilate_cross_img, diamond) #使用菱形腐蚀图像
dilate_x_img = cv2.dilate(image, x) #使用X膨胀原图像
erode_square_img = cv2.erode(dilate_x_img,square) #使用方形腐蚀图像
result = cv2.absdiff(erode_square_img, erode_diamond_img) #将两幅闭运算的图像相减获得角
retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY) #使用阈值获得二值图#在原图上用半径为5的圆圈将点标出。
for j in range(result.size):y = int(j / result.shape[0])x = int(j % result.shape[0])if result[x, y] == 255: #result[] 只能传入整型cv2.circle(image,(y,x),5,(255,0,0))
cv2.imshow("original_image", original_image)
cv2.imshow("Result", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
四、礼帽/顶帽,黑帽 算法
该算法可以图像识别的预处理,用于图像二值化后去除孤立点,如下图所示
import cv2
original_img = cv2.imread('image/1.jpg',0)
gray_img = cv2.resize(original_img,None,fx=0.8, fy=0.8, interpolation = cv2.INTER_CUBIC) #图形太大了缩小一点
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) #定义矩形结构元素(核大小为3效果好)
TOPHAT_img = cv2.morphologyEx(gray_img, cv2.MORPH_TOPHAT, kernel) #顶帽运算
BLACKHAT_img = cv2.morphologyEx(gray_img, cv2.MORPH_BLACKHAT, kernel) #黒帽运算
bitwiseXor_gray = cv2.bitwise_xor(gray_img,TOPHAT_img)
#显示如下腐蚀后的图像
cv2.imshow("gray_img", gray_img)
cv2.imshow("TOPHAT_img", TOPHAT_img)
cv2.imshow("BLACKHAT_img", BLACKHAT_img)
cv2.imshow("bitwiseXor_gray",bitwiseXor_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
三、开运算和闭运算
开运算和闭运算就是将腐蚀和膨胀按照一定的次序进行处理。 运算不可逆,即先开后闭并不能得到原先的图像。
为了获取图像中的主要对象:对一副二值图连续使用闭运算和开运算,或者消除图像中的噪声,也可以对图像先用开运算后用闭运算,不过这样也会消除一些破碎的对象。
开运算:先腐蚀后膨胀,用于移除由图像噪音形成的斑点。
闭运算:先膨胀后腐蚀,用来连接被误分为许多小块的对象;
"""
cv2.morphologyEx(src, # 输入图片op, # 需要处理类型的函数:(cv2.MORPH_OPEN,cv2.MORPH_CLOSE,cv2.MORPH_GRADIENT)kernel, # 卷积核大小dst=None, anchor=None, iterations=None, #迭代次数,默认1次borderType=None, borderValue=None)
"""
import cv2
import numpy as np
original_img = cv2.imread('original_img.png',0)
gray_res = cv2.resize(original_img,None,fx=0.8,fy=0.8,interpolation = cv2.INTER_CUBIC) #图形太大了缩小一点
# B, G, img = cv2.split(res)
# _,RedThresh = cv2.threshold(img,160,255,cv2.THRESH_BINARY) #设定红色通道阈值160(阈值影响开闭运算效果)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) #定义矩形结构元素closed1 = cv2.morphologyEx(gray_res, cv2.MORPH_CLOSE, kernel,iterations=1) #闭运算1
closed2 = cv2.morphologyEx(gray_res, cv2.MORPH_CLOSE, kernel,iterations=3) #闭运算2
opened1 = cv2.morphologyEx(gray_res, cv2.MORPH_OPEN, kernel,iterations=1) #开运算1
opened2 = cv2.morphologyEx(gray_res, cv2.MORPH_OPEN, kernel,iterations=3) #开运算2
gradient = cv2.morphologyEx(gray_res, cv2.MORPH_GRADIENT, kernel) #梯度#显示如下腐蚀后的图像
cv2.imshow("gray_res", gray_res)
cv2.imshow("Close1",closed1)
cv2.imshow("Close2",closed2)
cv2.imshow("Open1", opened1)
cv2.imshow("Open2", opened2)
cv2.imshow("gradient", gradient)cv2.waitKey(0)
cv2.destroyAllWindows()
二、腐蚀和膨胀
腐蚀:腐蚀会把物体的边界腐蚀掉,卷积核沿着图象滑动,如果卷积核对应的原图的所有像素值为1,那么中心元素就保持原来的值,其余部分变为零。主要应用在去除白噪声,也可以断开连在一起的物体。
膨胀:卷积核所对应的原图像的像素值只要有一个是1,中心像素值就是1。一般在除噪是,先腐蚀再膨胀开运算,因为腐蚀在去除白噪声的时候也会使图像缩小,所以我们之后要进行膨胀。当然也可以用来将两者物体连通。
import cv2
import numpy as np
import math
import matplotlib.pyplot as plttargetImg = cv2.imread('image/1.jpg')
kernel_4 = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
HSV = cv2.cvtColor(targetImg, cv2.COLOR_BGR2HSV) # 把BGR图像转换为HSV格式
Lower = np.array([0, 3, 5]) # 要识别颜色-红色的下限 ## 0 5 5 10 255 255
Upper = np.array([10, 255, 255]) # 要识别的颜色-红色的上限# mask是把HSV图片中在颜色范围内的区域变成白色,其他区域变成黑色
mask = cv2.inRange(HSV, Lower, Upper)
erosion = cv2.erode(mask, kernel_4, iterations=1)
erosion = cv2.erode(erosion, kernel_4, iterations=1)
dilation = cv2.dilate(erosion, kernel_4, iterations=1)
dilation = cv2.dilate(dilation, kernel_4, iterations=1)cv2.imshow("img", targetImg)
cv2.imshow("mask", mask)
cv2.imshow("target", target)
cv2.imshow("erosion", erosion)
cv2.imshow("dilation", dilation)
cv2.waitKey()
# cv2.imshow("cv_cut_img_circle", cv_cut_img_circle)
# return cropped
一、定义结构元素
形态学处理的核心就是定义结构元素,在OpenCV-Python中,可以使用其自带的getStructuringElement
函数,也可以直接使用NumPy的ndarray来定义一个结构元素。
(形象图如下:)
如下代码:为上图的十字形结构
当然还可以定义椭圆/矩形等:
椭圆:cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
矩形:cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
element = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
print("elemrnt":element )
------------------------------------------------
import numpy as np
NpKernel = np.uint8(np.zeros((5,5)))
for i in range(5):NpKernel[2, i] = 1NpKernel[i, 2] = 1
print("NpKernel ",NpKernel )上述结果输出(相同):
array([[0, 0, 1, 0, 0],[0, 0, 1, 0, 0],[1, 1, 1, 1, 1],[0, 0, 1, 0, 0],[0, 0, 1, 0, 0]], dtype=uint8)
参考书籍:
《opencv基础开发教程 》
参考blog:
https://blog.csdn.net/sunny2038/article/details/9137759
https://blog.csdn.net/on2way/article/details/46850813
https://blog.csdn.net/wsp_1138886114/article/details/82917661
相关文章:

【 HihoCoder】1082 The Marshtomp has seen it all before (暴力 或 脑力)
https://vjudge.net/problem/HihoCoder-1082 暴力 #include <iostream> #include <cstring>using namespace std;char s[205];int main() {int i;while(gets(s)){i 0;int len strlen(s);while(i<len){if((s[i]m||s[i]M)&&(s[i1]a||s[i1]A)&&am…

java 多维数组转化为字符串
int[][] a {{1,2,3},{4,5,7}};System.out.println(Arrays.deepToString(a)); Arrays.deepToString()此方法是为了将多维数组转换为字符串而设计的。 三维二维都可以解决;转载于:https://www.cnblogs.com/lishuaiqi/p/10428612.html

python-opencv 轮廓检测
轮廓检测 图像处理中经常用到轮廓检测,OpenCV-python接口中使用cv2.findContours()函数来查找检测物体的轮廓。 import cv2img cv2.imread(D:\\test\\contour.jpg) gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, binary cv2.threshold(gray,127,255,cv2.THRESH_BINARY)…

JavaDate类
在JDK1.0中,Date类是唯一的一个代表时间的类,但是由于Date类不便于实现国际化,所以从JDK1.1版本开始,推荐使用Calendar类进行时间和日期处理。这里简单介绍一下Date类的使用。1、使用Date类代表当前系统时间Date d new Date();Sy…
Jupyter Notebook使用教程
1、启动 在终端中输入以下命令: jupyter notebook --allow-root执行命令之后,在终端中将会显示一系列notebook的服务器信息,同时浏览器将会自动启动Jupyter Notebook。 启动过程中终端显示内容如下: $ jupyter notebook [I 08…

一次性理清JavaScript变量等高难度面试问题
主要是解决JavaScript中比较难懂的部分,当然了,这部分经常在面试题中露面,这篇文章主要是讲解解题思路,对新手会有很大帮助(如果你仔细看的话)。书籍方面,我看的是《你不知道的javascript》,精髓…

yolov3(一:模型训练)
第一部分:训练已有的voc datasets 搞清楚该算法的模型训练流程 Darknet是Joseph维护的开源的神经网络框架,使用C语言编写:https://pjreddie.com/darknet/yolo/ Darknet快速,易于安装,同时支持CPU和GPU计算࿱…

Ios生产证书申请(含推送证书)
一、Mac机上生成请求文件。 Mac机上点击证书助手 > 从证书颁发机构请求证书 > 得到CertificateSigningRequest.certSigningRequest请求文件(此请求证书建议一直保存,因为根证书的生成需要使用此请求文件,根证书多个app可以使用一个&…
【Python】SyntaxError: unexpected EOF while parsing
找到错误的地方是 少打了半个括号 emmm 1、可能是语法问题,需要自己检查代码 2、可能是用python2.7来运行python3.0的代码不兼容
华为云家庭视频监控帮你一起守护家
设想一下?离开家了突然想起家里空调没关怎么办?家里没人有陌生人入侵了怎么办?不在家家里老人出事了怎么办? 不用愁,总有办法解决的,这些日常生活中极容易遇到的事情,没有分身术的时候ÿ…
SLAM之特征匹配(三)————RANSAC------LO-RANSAC Algorithm
matlab 编译loransac,lapack mex ranH.c时一直链接错误。 原来mex在编译多个文件时要把所有的C文件都列出来。命令如下: mex loransacH.mex.c ranH.c utools.c Htools.c lapwrap.c matutl.c rtools.c -ID:\lapack\headers\lapack -LD:\lapack - lcbia.l…

【Codeforces】1136C Nastya Is Transposing Matrices (矩阵转置)
http://codeforces.com/contest/1136/problem/C 第一个矩阵可否通过转置,变换成第二个矩阵,可以的话输出“YES”,不可以的话,输出“NO” 转置之后,对角线元素是不变的 用map,或者vector 都可以 #includ…

linux基础篇-02,linux时间管理date hwclock cal 简述
################################################时间管理1,date:系统时钟查看当前系统时间[rootJameszhan etc]# date2016年 11月 14日 星期一 20:16:37 CST################################################设定系统时间 2016年 07月 20日 星期三 10:30:00 CST…

Spark shuffle调优
Spark shuffle是什么Shuffle在Spark中即是把父RDD中的KV对按照Key重新分区,从而得到一个新的RDD。也就是说原本同属于父RDD同一个分区的数据需要进入到子RDD的不同的分区。现在的spark版本默认使用的是sortshuffle;shuffle在哪里产生shuffle在spark的算子中产生,也就…

多传感器融合之滤波(一)——卡尔曼滤波(KF)推导
c参考资料:https://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/ 卡尔曼滤波本质上是一个数据融合算法,将具有同样测量目的、来自不同传感器、(可能) 具有不同单位 (unit) 的数据融合在一起,得到一个更精确的目的测量值。 卡尔…

【HDU】1284 钱币兑换问题 (想一想)
http://acm.hdu.edu.cn/showproblem.php?pid1284 除以三,看最多能放多少个三分的硬币,加一表示全部都是一分的硬币着一种情况。之后用一个循环看一下,有多少种情况 因为确定了有几个三分,有几个两分,一分的也就自然…

抓取网页的脚本 【修复】
之前张耀老师的网页脚本由于51cto升级,课程列表页面改用javascript失效了笔者发现视频课程页面右边的列表都为静态化后的视频课程地址,遂将老师初始版本的脚本进行了修改,在对视频课程页面使用时结果正常,遂将及修改后的脚本和部分…

实例规格 ECS (共享计算型)和 (通用型-原独享)性能上有什么区别?...
实例规格 ECS (共享计算型)和 (通用型-原独享)性能上有什么区别? 实例规格 共享计算型 和 通用型(原独享), 如果同样是2核4G 或者4核8G ; 性能上有什么差异/差距大吗? 内存型比通用性性能好些,而且CPU和内存配比: 通用型为1:2&…

yolov3(二:车牌识别)
0.按照:https://blog.csdn.net/Darlingqiang/article/details/103889245步骤训练自己的模型 1.下载[data.zip]:链接: https://pan.baidu.com/s/1NahLmB5YajUJT_Gk1OgN7A 提取码: 8888 2.进入data/voc目录下运行voc_label.bat重新生成2019_train.txt, 201…

[转]CSS hack大全详解
转自:CSS hack大全&详解 1、什么是CSS hack?CSS hack是通过在CSS样式中加入一些特殊的符号,让不同的浏览器识别不同的符号(什么样的浏览器识别什么样的符号是有标准的,CSS hack就是让你记住这个标准),…

【Python】打印魔方阵
1.将“1”放在第一行,中间一列; 2.从2开始至N*N各数按如下规律: 每一个数存放的行比上一个数的行减1; 每一个数存放的列比上一个数的列加1; 3.当一个数行为1,下一个数行为N; 4.当一个数列数为N,下一个…

读书笔记:《图解HTTP》第三章 HTTP报文
原文地址博客积累地址 HTTP报文的作用 HTTP报文时是HTTP进行请求和响应时用来交换信息的,可以理解它为搬东西的包裹,来搬运交换的信息报文流 HTTP报文在HTTP应用程序(客户端、服务器、代理)之间发送数据块,这些数据块以…

在Web.config或App.config中的添加自定义配置
.Net中的System.Configuration命名空间为我们在web.config或者app.config中自定义配置提供了完美的支持。最近看到一些项目中还在自定义xml文件做程序的配置,所以忍不住写一篇用系统自定义配置的随笔了。 如果你已经对自定义配置了如指掌,请忽略这篇文章…

yolov3(三:算法框架解析)
应用见: https://blog.csdn.net/Darlingqiang/article/details/103889245 https://blog.csdn.net/Darlingqiang/article/details/104040582 首先通过一些简单的应用实现去理解yolov3的网络框架,接着让我们开始对yolov3的网络框架解析之旅。 首先&…

【牛客】简单排序 (STL)
https://ac.nowcoder.com/acm/contest/547/F 首先将一系列数存入到数组中,然后利用set的upper_bound返回第一个大于他的函数,如果存在这样的,就把大于他的那个数删除,加入这个新的数,否则就表示序列中没有大于他的数&…

python基础04
python基础04 python2在编译安装时,可以通过参数 -----enable----unicodeucs2 或 -----enable--unicodeucs4 分别用于指定使用2个字节,4个字节表示一个Unicode字符。python3无法进行选择,默认使用usc4. 查看当前python中表示Unicode字符串时占…

【Java】字符串(一)
目录 一、创建字符串 二、连接字符串 连接多个字符串 连接其他数据类型 三、获取字符串的信息 获取字符串的长度 字符串查找 获取指定索引位置的字符 四、字符串操作 获取子字符串 去除空格 字符串的替换 判断字符串是否相等 按字典顺序比较两个字符串 字母大小…

每天一命令 git checkout
检出 checkout 是git常用命令之一.主要用于创建切换分支,覆盖本地修改等 git checkout 用于显示工作区,暂存区,版本库中文件的区别 git checkout -b branch 用于创建一个新的分支, git checkout branch 用于检出一个分支 git checkout [commit] --filename 用暂存…

python数据结构与算法:排序算法(面试经验总结)
快排:最优复杂度 O(n*logn) 最坏时间复杂度O(n^2)平均时间复杂度n^(1.3) 归并排序:最优/平均/最坏 时间复杂度均O(nlogn),但是内存占用为list大小的两倍,算法稳定 ####…

go微服务框架go-micro深度学习(一) 整体架构介绍
产品嘴里的一个小项目,从立项到开发上线,随着时间和需求的不断激增,会越来越复杂,变成一个大项目,如果前期项目架构没设计的不好,代码会越来越臃肿,难以维护,后期的每次产品迭代上线…