学习笔记(01):一学即懂的计算机视觉(第一季)-图像表示与描述

立即学习:https://edu.csdn.net/course/play/26281/327093?utm_source=blogtoedu

# -*- coding: utf-8 -*-
"""
Created on Wed Mar 11 09:18:24 2020

@author: steventf
"""
import os 
import numpy as np
import cv2 as cv
os.chdir(r'E:\python應用\圖像語音識別')
filename='./self.png'
img=cv.imread(filename)
cv.imshow('hello steventf',img)
# cv.waitKey()
cv.destroyAllWindows()

fn1='./tree.jpg'
fn1='./lena.jpg'
fn1='./opencvlog.png'
img=cv.imread(fn1)
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
cv.imshow('souce image',img)#原始圖片
cv.imshow('gray',gray)#灰度圖片
# cv.waitKey()
hsv=cv.cvtColor(img,cv.COLOR_BGR2HSV) #顏色空間轉換由BGR圖片轉換為HSV( H色調,S飽合度.V值)
#dst = cv.cvtColor( src, code[, dst[, dstCn]] )


cv.imshow('Hue',hsv[:,:, 0]) 
cv.imshow('Saturetion',hsv[:,:,1])
cv.imshow("Value",hsv[:,:,2])

#以下通道分離bgr[:, :, 0] 表示第0个通道 (blue) 1.green.2.red
cv.imshow('Blue',img[:,:,0])
cv.imshow('Green',img[:,:,1])
cv.imshow('Red',img[:,:,2])
cv.destroyAllWindows()


def gauss_noise(image,mean=0,var=0.001):
    '''
    添加高斯噪聲
    mean:均值 
    Var:方差
    '''
    image=np.array(image/255,dtype=float)
    noise=np.random.normal(mean,var**0.5,image.shape)
    out=image+noise
    if out.min()<0:
        low_clip=-1.
    else:
        low_clip=0.
    out=np.clip(out,low_clip,1.0)
    out=np.uint8(out*255)
    # cv.imshow('Gauss',out)
    return out


fn2=r'./lena.jpg'
img=cv.imread(fn2)
cv.imshow('source',img)
img=gauss_noise(img) #原圖像加入高斯噪聲


blur=cv.blur(img,(5,5))#平均濾波
gauss=cv.GaussianBlur(img,(5,5),0)#高斯濾波
median=cv.medianBlur(img,5) #中值濾波
bailateral=cv.bilateralFilter(img,5,150,150) #雙邊濾波

cv.imshow('Image',img)
cv.imshow('blurred',blur)
cv.imshow('Gauss',gauss)
cv.imshow('Median filtered',median)  #中位濾波對孤立點處理較好.特別對椒鹽濾波較好.
cv.imshow('bilateral filtered',bailateral)

cv.waitKey()
cv.destroyAllWindows()

#边缘检测
fn2='./lena.jpg'
img=cv.imread(fn2,0)
#sobelt (塞波尔音译) 算子边缘检测
# ddepth目标图像的所需深度,包括CV_16S/CV_32F/CV_64F等
#ksize 滤波大少,通常可选(5,5)或(3,3),或直接使用缺省修士
#dst = cv2.Sobel( src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]] )
sobel=cv.Sobel(img,cv.CV_16S,1,0,ksize=3)
#Laplacian 拉普拉斯边缘检测
#dst = cv2.Laplacian( src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]] )

laplacian=cv.Laplacian(img,cv.CV_16S)
# Canny 边缘检测,量小阈值50最大阈值120
#dst = cv2.Canny( image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]] )
canny=cv.Canny(img,50,120)
#显示sobel,laplacian 边缘检测结果
sobel_show=cv.convertScaleAbs(sobel)
lap_show=cv.convertScaleAbs(laplacian)
cv.imshow('sobel',sobel_show)
cv.imshow('laplacian',lap_show)

#显示Canny边缘检测结果
cv.imshow('Canny',canny)
'''
#形态学滤波
#dst = cv2.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] )
# op 形态学操作,包括MORPH_ERODE, MORPH_DILATE, MORPH_OPEN,
MORPH_CLOSE,MORPH_GRADIENT, MORPH_TOPHAT,
MORPH_BLACKHAT, MORPH_HITMISS
kernel 滤波结构元素,参见getStructuringElemen
iterations 进行操作的次数
dst = cv2.getStructuringElement( shape, ksize[, anchor] )
'''
nimg=gauss_noise(img)
kernel=cv.getStructuringElement(cv.MORPH_CROSS,(3,3))
eroded=cv.erode(img,kernel)
dilated=cv.dilate(img,kernel)

opened=cv.morphologyEx(nimg,cv.MORPH_OPEN,kernel)
closed=cv.morphologyEx(opened,cv.MORPH_CLOSE,kernel)
#以下分别是原始图像腐蚀,膨胀,以及加噪声图像开\闭运算结果
cv.imshow('Noised image',nimg)
cv.imshow('Eroded image',eroded)
cv.imshow('Dilated image',dilated)
cv.imshow('opened image',opened)
cv.imshow('Closed image',closed)


#以下分别计算 并显示梯度顶帽和黑帽变换结果
gradient=cv.morphologyEx(img,cv.MORPH_GRADIENT,kernel)
cv.imshow('Image gradient',gradient)
#顶帽变换适合于背景是暗,前景是亮的,底帽变换正好相返.
tophat=cv.morphologyEx(img,cv.MORPH_TOPHAT,kernel)
bottomhat=cv.morphologyEx(img,cv.MORPH_BLACKHAT,kernel)
cv.imshow('tophat',tophat)
cv.imshow('blackhat',bottomhat)

#利用顶帽和黑帽变换进行图像增强,并显示结果
enhanced=img+tophat-bottomhat
cv.imshow('Enhanced image',enhanced)

#计算击中或不击中(HMT)变换结果并显示

kernel=np.array(([0,1,0],[1,-1,1],[0,1,0]),dtype='int')
hmt=cv.morphologyEx(img,cv.MORPH_HITMISS,kernel)
cv.imshow('hit or miss transform',hmt)

#图像的几保变换:放缩/翻转

fn2=r'./lena.jpg'
img=cv.imread(fn2)
cv.imshow('source',img)
w,h=img.shape[0:2]
resized=cv.resize(img,(int(w/4),int(h/2)))
cv.imshow('resized',resized)
#0 上下反转 1 左右  -1 上下&左右
for i in range(-1,2):
    flipped=cv.flip(img,i)
    cv.imshow('flipped{}'.format(i),flipped)
    
#图像的距离变换
'''
dst = cv.distanceTransform( src, distanceType, maskSize[, dst[, dstType]] )
distanceType : 距离计算方式, DIST_L1, DIST_L2或 DIST_C;
maskSize : 掩模尺寸, 可取DIST_MASK_PRECISE或DIST_MASK_3, 5等。
'''
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,thr=cv.threshold(gray,100,25,cv.THRESH_OTSU)
dist=cv.distanceTransform(thr,cv.DIST_L2,cv.DIST_MASK_3)
dist_norm=cv.convertScaleAbs(dist)

cv.imshow('log-disitance transform',dist_norm)

#实现log-polar变换
'''
dst = cv.logPolar( src, center, M, flags[, dst] )
center : 变换中心点;
M : 幅值尺度参数
flags: 标志。 是插值方法和下面选项的组合: CV_WARP_FILL_OUTLIERS 填充目标图像中的所
有像素; CV_WARP_INVERSE_MAP 表示矩阵是从目标图像到源图像的反变换
'''
center=(w/2,h/2)
maxRadius=0.7*min(center)
M=w/cv.log(maxRadius)
print(maxRadius,M[0])
log_polar=cv.logPolar(img,center,M[0]*0.8,cv.INTER_LINEAR+cv.WARP_FILL_OUTLIERS)
cv.imshow('log-polar',log_polar)

#实现灰度直方图和直方图均衡化
'''
matplotlib.pyplot.hist(x, bins=None, range=None, ...)
bins : 多少个柱;
range: 显示的范围。

直方图均衡化
dst = cv.equalizeHist( src [, dst] )

'''

import matplotlib.pyplot as plt
plt.hist(gray.ravel(),256,[0,256])
plt.show()
equa=cv.equalizeHist(gray)
cv.imshow('equalized image ',equa)

#实现Hough变换
'''
lines = cv.HoughLines( image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]] )
image: 输入图像, 应为二值图像, 通常使用边缘检测结果;
rho: 线段以像素为单位的距离精度, double类型的, 推荐用1.0
theta: 线段以弧度为单位的角度精度, 推荐用numpy.pi/180
threshod: 累加平面的阈值参数, int类型, 超过设定阈值才被检测出线段, 值越大, 基本上意味着检出的线
段越长, 检出的线段个数越少
'''
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
edges=cv.Canny(gray,50,150)
cv.imshow('edges',edges)
disp_edge=cv.cvtColor(edges, cv.COLOR_GRAY2BGR)
lines=cv.HoughLinesP(edges,1,1*np.pi/180,10)
for line in lines:
    for x1,y1,x2,y2 in line:
        #画出直线
        cv.line(disp_edge,(x1,y1),(x2,y2),(0,255,0),1)
    pass

print('line count:',len(lines))

cv.imshow('disp_edge',disp_edge)


#檢測圖中的米粒
'''
1.取得圖像
2.圖像預處理或後處理
3.基於灰度的閾值分割
4.得到最終結果
'''
filename=r'./rice.png'
image=cv.imread(filename)
cv.imshow('source image',image)
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow('gary rice',gray)
#大津OTSU算法灰度閾值化
thr,bw=cv.threshold(gray,0,0xff,cv.THRESH_OTSU)
print('threshold is :',thr)

#画出灰度直方图
plt.hist(gray.ravel(),256,[0,256])
plt.show()

element=cv.getStructuringElement(cv.MORPH_CROSS,(3,3))
bw=cv.morphologyEx(bw, cv.MORPH_OPEN, element)

import copy                   
seg=copy.deepcopy(bw)
#计算轮廓
'''
image, contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy[,offset]]] )
image : 单通道图像矩阵, 可以是灰度图, 但更常用的是经过边缘检测算子处理后的二值图像;
contours : 定义为“vector<vector<Point>> contours” , 是一个轮廓列表;
hierarchy : 存在嵌套轮廓时, 分别为第i个轮廓的后一个轮廓、 前一个轮廓、 父轮廓、 内嵌轮廓的索引
编号;
mode : 定义轮廓的检索模式, 包括CV_RETR_EXTERNAL只检测最外围轮廓, CV_RETR_LIST检测所有
轮廓, 但不建立等级关系等;
method : 包括CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息, 把所有轮廓拐点处的点保存入
contours等;
offset : 所有的轮廓信息相对于原始图像对应点的偏移量, 缺省不设置。
'''
cnts,hier=cv.findContours(seg,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)

count=0
#遍历所有区域,并去除面积过小的
for i in range(len(cnts),0,-1):
    c=cnts[i-1]
    area=cv.contourArea(c)
    if area<10:
        continue
    count+=1
    print('blob',i,':',area)
    #区域画杠并标记
    x,y,w,h=cv.boundingRect(c)
    cv.rectangle(image,(x,y),(x+w,y+h),(0,0,0xff),1)
    cv.putText(image,str(count),(x,y),cv.FONT_HERSHEY_SIMPLEX,0.5,(0,0xff,0))
print('米粒的数量:',count)
cv.imshow('源图',image)
cv.imshow('阈值化图',bw)


#OpenCV实现区域漫水填充
'''
漫水填充(区域生长法)
retval, image, mask, rect = cv.floodFill( image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]] )
• image: 输入/输出1通道或3通道, 8位或浮点图像, 具体参数由之后的参数具体指明。
• mask: 操作掩模,。 它应该为单通道、 8位、 长和宽上都比输入图像 image 大两个像素点的图像。 第二个
版本的floodFill需要使用以及更新掩膜, 所以这个mask参数我们一定要将其准备好并填在此处。 需要注
意的是, 漫水填充不会填充掩膜mask的非零像素区域。 例如, 一个边缘检测算子的输出可以用来作为掩
膜, 以防止填充到边缘。 同样的, 也可以在多次的函数调用中使用同一个掩膜, 以保证填充的区域不会重
叠。 另外需要注意的是, 掩膜mask会比需填充的图像大, 所以 mask 中与输入图像(x,y)像素点相对应的
点的坐标为(x+1,y+1)。
• seedPoint: Point类型, 漫水填充算法的起始点。
• newVal: Scalar类型, 像素点被染色的值, 即在重绘区域像素的新值。
• rect: Rect*类型, 有默认值0, 可选的参数, 用于设置将要重绘区域的最小边界矩形区域。
• loDiff: Scalar类型, 有默认值Scalar( ), 表示当前观察像素值与其部件邻域像素值或者待加入该部件的种
子像素之间的亮度或颜色之负差( lower brightness/color difference) 的最大值。
• upDiff: Scalar类型, 有默认值Scalar( ), 表示当前观察像素值与其部件邻域像素值或者待加入该部件的种
子像素之间的亮度或颜色之正差( lower brightness/color difference) 的最大值。
• flags: int类型, 操作标志符, 此参数包含三个部分, 控制算法连通性等。

'''

        

   

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值