1. Введение в OpenCV
OpenCV — это кроссплатформенная библиотека программного обеспечения для компьютерного зрения и машинного обучения, выпущенная под лицензией BSD (с открытым исходным кодом), которая может работать в операционных системах Linux, Windows, Android и Mac OS (ожидается, что в будущем она будет работать на Harmony OS).
Он легкий и эффективный — он состоит из ряда функций C и небольшого количества классов C++, предоставляет интерфейсы для таких языков, как Python, Ruby и MATLAB, и реализует множество общих алгоритмов обработки изображений и компьютерного зрения.
2. Модуль Opencv
модуль |
Функции |
Core |
Основные модули, включая самые основные операции |
Imgproc |
Модуль обработки изображений |
Objdectect |
модуль обнаружения целей |
Feature2D |
Модуль обнаружения 2D-элементов |
Video |
Модуль обработки видео |
HighGUI |
Графический пользовательский интерфейс высокого уровня |
Calib3d |
Модуль 3D-реконструкции |
ML |
Модуль машинного обучения |
FLANN |
модуль поиска ближайшего соседа |
Stitching |
Модуль сшивания изображений |
Photo |
компьютерная визуализация |
Superres |
Модуль сверхвысокого разрешения |
GPU |
Модуль параллельного ускорения графического процессора |
3. Обзор OpenCV
Каждый модуль в среде OpenCV содержит большое количество методов компьютерного зрения, и каждый модуль может быть уникальным и мощным.
В этой статье будет представлен самый важный модуль библиотеки OpenCV: Imgproc (модуль обработки изображений).
Модуль обработки изображений включает в себя: чтение, отображение и хранение изображений, геометрические операции;Преобразование оттенков серого;геометрическое преобразование;гладить, точить;Математическая морфология;пороговая сегментация;обнаружение края;цветовое пространство; рисунок формы и т. д.
-
Изображение читать, отображать, сохранять
функция |
Функции |
cv2.imread( ) |
чтение изображений |
cv2.imshow( ) |
Отображение изображения |
cv2.imwrite( ) |
сохранение изображения |
"""图像读取、显示、保存"""
img = cv2.imread('shiyuan.png')
cv2.imwrite('shi.png',img)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
функция |
Функции |
img1+img2 |
добавление изображения |
cv2.addWeight( ) |
слияние изображений |
"""几何运算"""
img1 = cv2.imread('shiyuan.png')
img2 = cv2.imread('lizi.png')
img3 = cv2.resize(img1,(300,300))+cv2.resize(img2,(300,300))
img4 = cv2.addWeighted(cv2.resize(img1,(300,300)),0.3,cv2.resize(img2,(300,300)),0.7,20)
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
-
Преобразование оттенков серого
функция |
Функции |
логарифмическое преобразование |
Преобразование изображения в оттенки серого |
Гамма-преобразование |
Преобразование изображения в оттенки серого |
Выравнивание гистограммы |
Преобразование изображения в оттенки серого |
Спецификация гистограммы |
Преобразование изображения в оттенки серого |
"""灰度变换"""
import cv2
import copy
img = cv2.imread('bai.png',1)
img1 = cv2.imread('bai.png',0)
img = cv2.resize(img,(400,300))
img1 = cv2.resize(img,(400,300))
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#伽马变换
gamma = copy.deepcopy(gray)
rows = img.shape[0]
cols = img.shape[1]
for i in range(rows):
for j in range(cols):
gamma[i][j]=3*pow(gamma[i][j],0.8)
cv2.imshow('img',img)
cv2.imshow('gray',img1)
cv2.imshow('gamma',gamma)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""灰度变换"""
import cv2
import copy
import math
img = cv2.imread('bai.png',1)
img1 = cv2.imread('bai.png',0)
img = cv2.resize(img,(400,300))
img1 = cv2.resize(img,(400,300))
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#对数变换
logc = copy.deepcopy(gray)
rows=img.shape[0]
cols=img.shape[1]
for i in range(rows):
for j in range(cols):
logc[i][j] = 3 * math.log(1 + logc[i][j])
cv2.imshow('img',img)
cv2.imshow('gray',img1)
cv2.imshow('logc',logc)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""灰度变换"""
import cv2
import copy
import math
img = cv2.imread('bai.png',1)
img1 = cv2.imread('bai.png',0)
img = cv2.resize(img,(400,300))
img1 = cv2.resize(img,(400,300))
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 反色变换
cover=copy.deepcopy(gray)
rows=img.shape[0]
cols=img.shape[1]
for i in range(rows):
for j in range(cols):
cover[i][j]=255-cover[i][j]
#通过窗口展示图片 第一个参数为窗口名 第二个为读取的图片变量
cv2.imshow('img',img)
cv2.imshow('gray',img1)
cv2.imshow('cover',cover)
cv2.waitKey(0)
cv2.destroyAllWindows()
#直方图规定化
import cv2
import numpy as np
import matplotlib.pyplot as plt
img0=cv2.imread('hua.png')#读取原图片
scr=cv2.imread('tu.png')#读取目标图片
#把两张图片转成真正的灰度图片,因为自己只会做灰度图片的规定化
img0=cv2.cvtColor(img0,cv2.COLOR_BGR2GRAY)
img=img0.copy()#用于之后做对比图
scr=cv2.cvtColor(scr,cv2.COLOR_BGR2GRAY)
mHist1=[]
mNum1=[]
inhist1=[]
mHist2=[]
mNum2=[]
inhist2=[]
#对原图像进行均衡化
for i in range(256):
mHist1.append(0)
row,col=img.shape#获取原图像像素点的宽度和高度
for i in range(row):
for j in range(col):
mHist1[img[i,j]]= mHist1[img[i,j]]+1#统计灰度值的个数
mNum1.append(mHist1[0]/img.size)
for i in range(0,255):
mNum1.append(mNum1[i]+mHist1[i+1]/img.size)
for i in range(256):
inhist1.append(round(255*mNum1[i]))
#对目标图像进行均衡化
for i in range(256):
mHist2.append(0)
rows,cols=scr.shape#获取目标图像像素点的宽度和高度
for i in range(rows):
for j in range(cols):
mHist2[scr[i,j]]= mHist2[scr[i,j]]+1#统计灰度值的个数
mNum2.append(mHist2[0]/scr.size)
for i in range(0,255):
mNum2.append(mNum2[i]+mHist2[i+1]/scr.size)
for i in range(256):
inhist2.append(round(255*mNum2[i]))
-
геометрическое преобразование
функция |
Функции |
cv2.resize( ) |
Масштабирование изображения |
cv2.warpAffine( ) |
панорамирование изображения |
cv2.getRotationMatrix2D( ) cv2.warpAffine( ) |
Поворот изображения |
cv2.getAffineTransform( ) cv2.warpAffine( ) |
Аффинное преобразование |
cv2.getPerspectiveTransform( ) cv2.warpPerspective( ) |
трансформация передачи |
cv2.pyrUp( ) |
Повышение частоты дискретизации пирамиды Гаусса |
cv2.pyrDown( ) |
Даунсемплинг пирамиды Гаусса |
img-cv2.pyrUp(cv2.pyrDown(img)) |
Пирамида Лапласа |
"""几何变换"""
img = cv2.imread('shiyuan.png')
img1 = cv2.resize(img,(300,300))
M = np.float32([[1,0,30],[0,1,60]])
img2 = cv2.warpAffine(img1,M,(300,300))
img2 = cv2.putText(img2,'panning',(20,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)
M = cv2.getRotationMatrix2D(((300-1)/2.0,(300-1)/2.0),45,1)
img3 = cv2.warpAffine(img1,M,(300,300))
img3 = cv2.putText(img3,'rotation',(20,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)
matr1 = np.float32([[50,50],[200,50],[50,200]])
matr2 = np.float32([[10,100],[200,50],[100,250]])
M = cv2.getAffineTransform(matr1,matr2)
img4 = cv2.warpAffine(img1,M,(300,300))
img4 = cv2.putText(img4,'affine',(20,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)
matr1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
matr2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(matr1,matr2)
img5 = cv2.warpPerspective(img1,M,(300,300))
img5 = cv2.putText(img5,'perspective',(20,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.imshow('img5',img5)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""图像金字塔"""
import cv2
#高斯金字塔
def pyramid_demo(image):
level = 2
temp = image.copy()
pyramid_images = []
for i in range(level):
dst = cv2.pyrDown(temp)
pyramid_images.append(dst)
cv2.imshow("pyramid"+str(i+1), dst)
temp = dst.copy()
return pyramid_images
#拉普拉斯金字塔
def lapalian_demo(image):
pyramid_images = pyramid_demo(image)
level = len(pyramid_images)
for i in range(level-1, -1, -1):
if (i-1) < 0:
expand = cv2.pyrUp(pyramid_images[i], dstsize = image.shape[:2])
lpls = cv2.subtract(image, expand)
cv2.imshow("lapalian_down_"+str(i+1), lpls)
else:
expand = cv2.pyrUp(pyramid_images[i], dstsize = pyramid_images[i-1].shape[:2])
lpls = cv2.subtract(pyramid_images[i-1], expand)
cv2.imshow("lapalian_down_"+str(i+1), lpls)
src = cv2.resize(cv2.imread('shiyuan.png'),(256,256))
cv2.namedWindow('input_image')
cv2.imshow('input_image', src)
lapalian_demo(src)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""直方图均衡化"""
import cv2
import numpy as np
img = cv2.imread('bai.png',0)
img = cv2.resize(img,(400,300))
equ = cv2.equalizeHist(img)
cv2.imshow('img',equ)
cv2.waitKey()
cv2.destroyAllWindows()
функция |
Функции |
cv2.blur( ) |
средний фильтр |
cv2.GaussianBlur( ) |
фильтр Гаусса |
cv2.medianBlur( ) |
медианный фильтр |
cv2.bilateralFilter( ) |
двусторонняя фильтрация |
"""平滑、锐化"""
import cv2
img = cv2.imread('shiyuan.png')
img = cv2.resize(img,(300,300))
img1 = cv2.blur(img,(11,11))
img2 = cv2.GaussianBlur(img,(11,11),0)
img3 = cv2.medianBlur(img,11)
img4 = cv2.bilateralFilter(img,9,75,75)
M = np.ones((5, 5), np.float32) / 25
img5 = cv.filter2D(img, -1, M)
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.imshow('img5',img5)
cv2.waitKey(0)
cv2.destroyAllWindows()
-
Математическая морфология
"数学形态学"
import cv2
img = cv2.imread('shiyuan.png')
img = cv2.resize(img,(300,300))
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
img1 = cv2.dilate(img, kernel)
img2 = cv2.erode(img,kernel)
#设置结构元
kernel_rect=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
kernel_cross=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
kernel_ellipse=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
#图像开运算处理
open_rect=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel_rect)
open_cross=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel_cross)
open_ellipse=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel_ellipse)
#图像闭运算处理
close_rect=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel_rect)
close_cross=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel_cross)
close_ellipse=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel_ellipse)
gradient_rect = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel_rect)
gradient_cross = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel_cross)
gradient_ellipse = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel_ellipse)
#顶帽变换
tophat_rect=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel_rect)
tophat_cross=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel_cross)
tophat_ellipse=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel_ellipse)
#顶帽变换
blackhat_rect=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel_rect)
blackhat_cross=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel_cross)
blackhat_ellipse=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel_ellipse)
cv2.imshow('blackhat_rect',blackhat_rect)
cv2.imshow('blackhat_cross',blackhat_cross)
cv2.imshow('blackhat_ellipse',blackhat_ellipse)
cv2.imshow('tophat_rect',tophat_rect)
cv2.imshow('tophat_cross',tophat_cross)
cv2.imshow('tophat_ellipse',tophat_ellipse)
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('open_rect',open_rect)
cv2.imshow('open_cross',open_cross)
cv2.imshow('open_ellipse',open_ellipse)
cv2.imshow('close_rect',close_rect)
cv2.imshow('close_cross',close_cross)
cv2.imshow('close_ellipse',close_ellipse)
cv2.imshow('gradient_rect',gradient_rect)
cv2.imshow('gradient_cross',gradient_cross)
cv2.imshow('gradient_ellipse',gradient_ellipse)
cv2.waitKey(0)
cv2.destroyAllWindows()
функция |
Функции |
cv2.threshold(,cv2.THRESH_BINARY) |
Порог бинаризации |
cv2.threshold(,cv2.THRESH_BINARY_INV) |
Порог дебинаризации |
cv2.threshold(,cv2.THRESH_TOZERO) |
Обработка нуля с низким порогом |
cv2.threshold(,cv2.THRESH_TOZERO_INV) |
Надпороговая обработка нуля |
cv2.threshold(,cv2.THRESH_OSTU) |
Алгоритм Оцу |
cv2.threshold(,cv2.THRESH_TRIANGLE) |
пороговое значение усечения |
cv2.adaptiveThreshold(,,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,) |
Адаптивный порог |
cv2.adaptiveThreshold(,,cv2.ADAPTIVE_THRESH_MEAN_C,) |
Адаптивный порог |
"阈值分割"
import cv2
img = cv2.imread('shiyuan.png')
img = cv2.resize(img,(400,300))
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,img1 = cv2.threshold(img,110,255,cv2.THRESH_BINARY)
ret,img2 = cv2.threshold(img,110,255,cv2.THRESH_BINARY_INV)
ret,img3 = cv2.threshold(img,110,255,cv2.THRESH_TOZERO)
ret,img4 = cv2.threshold(img,110,255,cv2.THRESH_TOZERO_INV)
ret,img5 = cv2.threshold(img,110,255,cv2.THRESH_TRUNC)
ret,img6 = cv2.threshold(img,110,255,cv2.THRESH_TRIANGLE)
ret,img7 = cv2.threshold(img,110,255,cv2.THRESH_OTSU)
ret,img8 = cv2.threshold(cv2.GaussianBlur(img,(7,7),0),110,255,cv2.THRESH_OTSU)
img9 = cv2.adaptiveThreshold(img,127, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 9, 11)
img10 = cv2.adaptiveThreshold(img,127,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,9,11)
cv2.imshow('img',img)
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.imshow('img5',img5)
cv2.imshow('img6',img6)
cv2.imshow('img7',img7)
cv2.imshow('img8',img8)
cv2.imshow('img9',img9)
cv2.imshow('img10',img10)
cv2.waitKey(0)
cv2.destroyAllWindows()
функция |
Функции |
cv2.Canny( ) |
Хитрый оператор |
cv2.findContours( ) |
Обнаружение контура |
cv2.filter2D( ) |
извлечение края |
"边缘检测"
import cv2
img = cv2.imread('bai.png')
img = cv2.resize(img,(400,300))
img1 = cv2.Canny(img,123,5)
cv2.imshow('img1',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""边缘检测"""
import cv2
img = cv2.imread('bai.png')
img = cv2.resize(img,(400,300))
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img,contours,-1,(0,0,255),1)
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""边缘检测"""
import cv2
import numpy as np
def find_contours(kernel):
img = cv2.imread('bai.png')
img = cv2.resize(img,(400,300))
img1 = cv2.filter2D(img,-1,kernel)
cv2.imshow('img1',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
kernel1 = np.array((
[0.0625, 0.125, 0.0625],
[0.125, 0.25, 0.125],
[0.0625, 0.125, 0.0625]), dtype="float32")
#Sobel算子
kernel2 = np.array(([-1,-2,-1],
[0,0,0],
[1,2,1]))
kernel3 = np.array(([-2,-1,0],
[-1,1,1],
[0,-1,-2]))
kernel4 = np.array([[-1,-1,-1],
[-1,8,-1],
[-1,-1,-1]])
kernel5 = np.array([[0,-1,0],
[-1,5,-1],
[0,-1,0]])
kernel6 = np.array([[0,1,0],
[1,-4,1],
[0,1,0]])
find_contours(kernel1)
find_contours(kernel2)
find_contours(kernel3)
find_contours(kernel4)
find_contours(kernel5)
find_contours(kernel6)
функция |
Функции |
cv2.cvtColor(,cv2.COLOR_BGR2GRAY) |
изображение в градациях серого |
cv2.cvtColor(,cv2.COLOR_BGR2HSV) |
RGB в HSV |
"""色彩空间"""
import cv2
img = cv2.imread('bai.png')
img = cv2.resize(img,(400,300))
img1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
функция |
Функции |
cv2.line( ) |
рисовать прямые линии |
cv2.circle( ) |
нарисовать круг |
cv2.ellipse( ) |
нарисовать эллипс |
cv2.rectangle( ) |
нарисовать прямоугольник |
cv2.arrowedLine( ) |
рисовать стрелки |
cv2.putText( ) |
рисовать текст |
"""形状绘制"""
import cv2
img = cv2.imread('bai.png')
img = cv2.resize(img,(400,300))
imgx = img.copy()
imgy = img.copy()
imgz = img.copy()
imgw = img.copy()
img = cv2.resize(img,(400,300))
img1 = cv2.line(img,(10,10),(200,300),(0,0,255),2)
img2 = cv2.circle(imgx,(60,60),30,(0,0,213),-1)
img3 = cv2.rectangle(imgy,(10,10),(100,80),(0,0,200),2)
img4 = cv2.ellipse(imgz,(256,256),(50,40),0,5,360,(20,213,79),-1)
font=cv2.FONT_HERSHEY_SIMPLEX
img5 = cv2.putText(imgw,'opencv',(80,90), font, 2,(255,255,255),3)
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.imshow('img5',img5)
cv2.waitKey(0)
cv2.destroyAllWindows()
напиши в конце
информационный пакет
Следующим выпуском будет библиотека sklearn. Эта библиотека — лучший выбор для машинного обучения. Добро пожаловать на место!