最近正在做一个关于幅值提取的毕设,中间走了很多弯路,也看了很多大神的文章,最终经过我不懈努力解决了这个问题,特发此文与大家分享,如果有什么问题欢迎大家留言交流。
我用来搭建开发环境的软件是:PyCharm Community Edition +Anaconda3+Opencv
相关软件链接:
Anaconda在清华大学开源镜像站下载
链接: https://mirrors.tuna.tsinghua.edu.cn/.
PyCharm Community Edition 在官方网站下载,社区版免费
https://www.jetbrains.com/pycharm/download/#section=windows
当然也可以微信关注下:软件管家这个公众号,有大量免费软件
Opencv下载
详细信息参考:y = wX + b博主写的下载及安装教程,个人感觉很详细
https://blog.csdn.net/iracer/article/details/80498732
下面就开始项目吧,以下面这幅图为例子:
我们要开展的工作:分别提取左边和右边的最大幅值(最大纵坐标-最小纵坐标),思路是将图片分成两个子图,然后遍历两个子图搜索这两个最大值。
1、读入图片进行灰度处理
image = cv2.imread("F:\\proposal\\normalphotos\\a4.png", cv2.IMREAD_COLOR)
image2 = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
2、搜索二值图像上所有像素为(0,0,0)的点(黑色)
#这是一幅灰度化的图像遍历全部图像,并记录像素为(0,0,0)点的坐标
def cxsearch(image):
k = 0
height=image.shape[0]
print("图像高", height)
width=image.shape[1]
print("图像宽", width)
x = [0] * 5000
for i in range(height): # 遍历图像的高
for j in range(width): # 遍历图像的宽
pixel = image[i, j] # 读取该点的像素值
if all(pixel == (0, 0, 0)):
x[k] = i # 存取像素点是黑色的的纵坐标
# print(x[k])
k += 1
return x
3、寻找最大幅值
#注意传入的是一个包含所有黑色点的纵坐标数组
def matdistance(*discance):
price= discance[0]
#print(discance)
mindistance = price[0]
matdistance = price[0]
#print(price[0])
matprofit = 0
w=len(price)
for i in range(w):
if price[i]!=0 :
if price[i]<mindistance or price[i]==mindistance :
mindistance=price[i]
#print(mindistance)
if price[i]>matdistance or price[i]==matdistance :
matdistance=price[i]
print("最低点纵坐标",mindistance)
print("最高点纵坐标",matdistance)
matprofit=matdistance-mindistance
return matprofit
4、划为子图
a=image.shape[0] #图片的高
b=image.shape[1] #图片的宽
#print(a)
#print(b)
#将图片分为两![在这里插入图片描述](https://img-blog.csdnimg.cn/20200331110527961.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FsbGFuX2JhYmE=,size_16,color_FFFFFF,t_70#pic_center)部分
dis_h = a
dis_w = int(b/2)
sub1=image[1:dis_h,1:dis_w]#第一心音
sub2=image[1:dis_h,dis_w : :]#第二心音图
5、最后运行效果图
(原图)
(子图1)
(子图2)
(提取结果)
6、所有代码呈上
import cv2 #导入opencv
import os
import numpy as np
#寻找最大值函数传进参数为数组
def matdistance(*discance):
price= discance[0]
#print(discance)
mindistance = price[0]
matdistance = price[0]
#print(price[0])
matprofit = 0
w=len(price)
for i in range(w):
if price[i]!=0 :
if price[i]<mindistance or price[i]==mindistance :
mindistance=price[i]
#print(mindistance)
if price[i]>matdistance or price[i]==matdistance :
matdistance=price[i]
print("最低点纵坐标",mindistance)
print("最高点纵坐标",matdistance)
matprofit=matdistance-mindistance
return matprofit
#遍历全部图像,并记录像素为(0,0,0)点的坐标
def cxsearch(image):
k = 0
height=image.shape[0]
print("图像高", height)
width=image.shape[1]
print("图像宽", width)
x = [0] * 5000
for i in range(height): # 遍历图像的高
for j in range(width): # 遍历图像的宽
pixel = image[i, j] # 读取该点的像素值
if all(pixel == (0, 0, 0)):
x[k] = i # 存取像素点是黑色的的纵坐标
# print(x[k])
k += 1
return x
image = cv2.imread("F:\\proposal\\normalphotos\\a4.png", cv2.IMREAD_COLOR) #读入图片
a=image.shape[0] #图片的高
b=image.shape[1] #图片的宽
#print(a)
#print(b)
#将图片分为两部分
dis_h = a
dis_w = int(b/2)
sub1=image[1:dis_h,1:dis_w]#第一心音
sub2=image[1:dis_h,dis_w : :]#第二心音图
#print("okokok",sub1.shape[0])
#print("ononon",sub1.shape[1])
z1=matdistance(cxsearch(sub1))#求取第一心音的最大幅值
z2=matdistance(cxsearch(sub2))#求取第二心音的最大幅值
print("第一心音最大幅值",z1)
print("第二心音最大幅值",z2)
cv2.namedWindow("orient", 0) #显示未分割的原始图
cv2.resizeWindow("orient", 640, 480);
cv2.imshow("orient", image)
cv2.namedWindow("orient1", 0)#显示分割的子图1
cv2.resizeWindow("orient1", 640, 480);
cv2.imshow("orient1", sub1)
cv2.namedWindow("orient2", 0)#显示分割的子图2
cv2.resizeWindow("orient2", 640, 480);
cv2.imshow("orient2", sub2)
cv2.waitKey(0)