实验目的
(1)掌握OpenCV 3在图像处理中常用函数的使用。
(2)熟练操作Anaconda环境中Jupyter Notebook的使用。
(3)熟悉OpenCV中傅里叶变化的原理。
实验原理
(1)熟练掌握Anaconda环境的安装及其基本操作。
(2)理解Jupyter Notebook的工作原理。
(3)将上机程序调试通过,并能独立完成课堂练习题目。
实验内容与步骤
在filters.py文件中实现这个函数:
import cv2
def strokeEdges(src,blurKsize=7,edgeKsize=5):
'''
该函数实现性能更好的边缘检测
这里使用medianBlur()作为模糊函数,使用Laplacian()作为边缘检测函数。在使用medianBlur()之后,
需要将图像从BGR色彩空间转换为灰度色彩空间。在得到Laplacian()函数结果之后,需要将图像转换为
黑色边缘和白色背景(之前是白色边缘黑色背景)。然后将其归一化,并乘以源图像以便能将边缘变黑。
args:
src:源图像数据 BGR色彩空间
blurKsize:模糊滤波卷积核的宽和高 小于3,不进行模糊处理
edgeKsize:边缘检测卷积核的宽和高
return:
dst:目标图像数据 灰度色彩空间
'''
if blurKsize >= 3:
#先模糊处理
blurredSrc = cv2.medianBlur(src,blurKsize)
cv2.imshow('blurredSrc',blurredSrc)
#BGR格式转化为灰度格式
graySrc = cv2.cvtColor(blurredSrc,cv2.COLOR_BGR2GRAY)
else:
graySrc = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
cv2.imshow('graySrc',graySrc)
#边缘检测 对灰度图像检测效果更好
cv2.Laplacian(graySrc,cv2.CV_8U,graySrc,ksize = edgeKsize)
cv2.imshow('laplacian',graySrc)
#颜色反向处理 并归一化
normalizedInverseAlpha = (1.0/255)*(255 - graySrc)
cv2.imshow('normalizedInverseAlpha',normalizedInverseAlpha)
#通道分离 B,G,R 单通道图像
channels = cv2.split(src)
cv2.imshow('B',channels[0])
#计算后的结果分别与每个通道相乘
for channel in channels:
#这里是点乘,即对应元素相乘
channel[:] = channel * normalizedInverseAlpha
cv2.imshow('B1',channels[0])
#通道合并(只能合并多个单通道成为多通道)
return cv2.merge(channels)
img = cv2.imread('car.jpg',cv2.IMREAD_COLOR)
dst = strokeEdges(img)
cv2.imshow('dst',dst)
cv2.waitKey()
cv2.destroyAllWindows()
参照chapter3.ipynb文件,把相关操作执行一遍
#Canny边缘检测
import cv2
import numpy as np
img = cv2.imread("flower.jpg")
cv2.imwrite("canny.jpg", cv2.Canny(img, 200, 300))
cv2.imshow("image", img)
cv2.imshow("canny", cv2.imread("canny.jpg"))
cv2.waitKey()
cv2.destroyAllWindows()
#轮廓检测
import cv2
import numpy as np
img = np.zeros((200, 200), dtype = np.uint8) # 创建一个200x200大小的黑色空白图像,
img[50:150, 50:150] = 255 # 在图像的中央放置一个白色方块
ret, thresh = cv2.threshold(img, 127, 255, 0) #对图像进行二值化操作
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 寻找轮廓
color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) # 颜色空间转换
img = cv2.drawContours(color, contours, -1, (0, 255, 0), 2) # 画出轮廓,-1,表示所有轮廓,画笔颜色为(0, 255, 0),即Green,粗细为3
cv2.imshow("contours",color)
cv2.waitKey()
cv2.destroyAllWindows()
#边界框、最小矩形区域和最小闭圆的轮廓
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512,3),np.uint8) #生成一个空彩色图像
cv2.rectangle(img,(20,20),(411,411),(55,255,155),5)
plt.imshow(img,'brg')
plt.show()
import cv2
import numpy as np
img = cv2.pyrDown(cv2.imread("hamper.jpeg", cv2.IMREAD_UNCHANGED))
ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)
contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
# find bounding box coordinates
# 现计算出一个简单的边界框
x, y, w, h = cv2.boundingRect(c) # 将轮廓信息转换成(x, y)坐标,并加上矩形的高度和宽度
cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2) # 画出矩形
# find minimum area
# 计算包围目标的最小矩形区域
rect = cv2.minAreaRect(c)
# calculate coordinate of the minimum area rectangle
box = cv2.boxPoints(rect)
# normalize coordinates to integers
box =np.int0(box)
# 注:OpenCV没有函数能直接从轮廓信息中计算出最小矩形顶点的坐标。所以需要计算出最小矩形区域,
# 然后计算这个矩形的顶点。由于计算出来的顶点坐标是浮点型,但是所得像素的坐标值是整数(不能获取像素的一部分),
# 所以需要做一个转换
# draw contours
cv2.drawContours(img, [box], 0, (0, 0, 255), 3) # 画出该矩形
# calculate center and radius of minimum enclosing circle
(x, y), radius = cv2.minEnclosingCircle(c) # 会返回一个二元组,第一个元素为圆心的坐标组成的元组,第二个元素为圆的半径值。
# cast to integers
center = (int(x), int(y))
radius = int(radius)
# draw the circle
img = cv2.circle(img, center, radius, (0, 255, 0), 2)
cv2.drawContours(img, contours, -1, (255, 0, 0), 1)
cv2.imshow("contours", img)
cv2.waitKey()
cv2.destroyAllWindows()
#凸轮廓与Douglas-Peucker算法
#可通过OpenCV的cv2.arcLength函数来得到轮廓的周长信息
epsilon = 0.01 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
#可通过OpenCV来有效地计算一个近似多边形,多边形周长与源轮廓周长之比就为ε。
#为了计算凸形状,需要用OpenCV的cv2.convexHull函数来获取处理过的轮廓信息,#代码为
hull = cv2.convexHull(cnt)
#直线和圆检测
#绘制直线:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512),np.uint8)#生成一个空灰度图像
cv2.line(img,(0,0),(511,511),255,5)
plt.imshow(img,'gray')
plt.show()
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512,3),np.uint8)#生成一个空彩色图像
cv2.line(img,(0,0),(511,511),(0,255,0),5)
plt.imshow(img,'brg')
plt.show()
#绘制圆
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512,3),np.uint8)#生成一个空彩色图像
cv2.circle(img,(100,100),50,(55,255,155),5)
plt.imshow(img,'brg')
plt.show()
#圆检测
import cv2
import numpy as np
planets = cv2.imread("planet_glow.jpg")
gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(gray_img, 5)
cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 120, param1=100, param2 = 30, minRadius = 0, maxRadius = 0)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(planets, (i[0], i[1]), i[2],(0, 255, 0),2)
# draw the center of the circle
cv2.circle(planets, (i[0], i[1]), 2, (0, 0,255), 3)
cv2.imwrite("planets_circles.jpg",planets)
cv2.imshow("HoughCircles", planets)
cv2.waitKey()
cv2.destroyAllWindows()
#绘制椭圆
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512,3),np.uint8)#生成一个空彩色图像
cv2.ellipse(img,(256,256),(150,100),0,0,180,250,-1)
#注意最后一个参数-1,表示对图像进行填充,默认是不填充的,如果去掉,只有椭圆轮廓了
plt.imshow(img,'brg')
plt.show()
程序练习
import cv2
img=cv2.imread('black.jpg',0)
t5,dst5=cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
cv2.imshow('img',img)
cv2.imshow('dst5',dst5)
if cv2.waitKey(0)==27:
cv2.destroyAllWindows()
import cv2
img=cv2.imread('black.jpg',0)
t6,dst6=cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
cv2.imshow('img',img)
cv2.imshow('dst6',dst6)
if cv2.waitKey(0)==27:
cv2.destroyAllWindows()
import cv2
img=cv2.imread('black.jpg',0)
t1,dst1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
t7,dst7=cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
cv2.imshow('dst1',dst1)
cv2.imshow('dst7',dst7)
if cv2.waitKey(0)==27:
cv2.destroyAllWindows()
import cv2
img=cv2.imread('guet.JPG')
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2BGRA)
t1,dst1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
t2,dst2=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
t3,dst3=cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
t4,dst4=cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
t5,dst5=cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
cv2.imshow('BINARY',dst1)
cv2.imshow('BINARY_INV',dst2)
cv2.imshow('TOZERO',dst3)
cv2.imshow('TOZERO_INV',dst4)
cv2.imshow('TRUNC',dst5)
if cv2.waitKey(0)==27:
cv2.destroyAllWindows()
import cv2
img=cv2.imread('guet.JPG')
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# athdMEAM=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,3)
# athdGAUS=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,5,3)
athdMEAM=cv2.adaptiveThreshold(img_gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,3)
athdGAUS=cv2.adaptiveThreshold(img_gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,5,3)
cv2.imshow('MEAM_C',athdMEAM)
cv2.imshow('GAUSSIAN_C',athdGAUS)
if cv2.waitKey(0)==27:
cv2.destroyAllWindows()
import cv2
img=cv2.imread('guet.JPG')
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
t1,dst1=cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)
t2,dst2=cv2.threshold(img_gray,0,255,(cv2.THRESH_BINARY + cv2.THRESH_OTSU))
cv2.putText(dst2,'best threshold:'+str(t2),(0,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,0),2)
cv2.imshow('BINARY',dst1)
cv2.imshow('OTSU',dst2)
if cv2.waitKey(0)==27:
cv2.destroyAllWindows()
#直线检测
import cv2
import numpy as np
img = cv2.imread("lines.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 120)
minLineLength = 20
maxLineGap = 5
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength, maxLineGap)
for x1, y1, x2, y2 in lines[0]:
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.imshow("edges", edges)
cv2.imshow("lines", img)
cv2.waitKey()
cv2.destroyAllWindows()