1. 程式人生 > >python進階—OpenCV之影象處理(一)

python進階—OpenCV之影象處理(一)

文章目錄


本篇接著記錄python-OpenCV的基礎部分:影象處理
https://docs.opencv.org/3.4.0/d6/d00/tutorial_py_root.html

顏色空間轉換

這裡主要說明BRG與HSV兩種應用最為廣泛的色彩空間

RGB色彩空間

在RGB顏色空間中,任意色光F都可以用R、G、B三色不同分量的相加混合而成:F=r[R]+r[G]+r[B]。RGB色彩空間還可以用一個三維的立方體來描述。當三基色分量都為0(最弱)時混合為黑色光;當三基色都為k(最大,值由儲存空間決定)時混合為白色光
在這裡插入圖片描述
RGB色彩空間根據每個分量在計算機中佔用的儲存位元組數分為如下幾種型別:

  • RGB555:RGB555是一種16位的RGB格式,各分量都用5位表示,剩下的一位不用。
    高位元組 -> 低位元組
    XRRRRRGGGGGBBBBB
  • RGB565:RGB565也是一種16位的RGB格式,但是R佔用5位,G佔用6位,B佔用5位。
  • RGB24R:GB24是一種24位的RGB格式,各分量佔用8位,取值範圍為0-255。
  • RGB32:RGB32是一種32位的RGB格式,各分量佔用8位,剩下的8位作Alpha通道或者不用。
    RGB色彩空間採用物理三基色表示,因而物理意義很清楚,適合彩色顯象管工作。然而這一體制並不適應人的視覺特點。因而,產生了其它不同的色彩空間表示法。

HSV色彩空間

HSV是一種將RGB色彩空間中的點在倒圓錐體中的表示方法。HSV即色相(Hue)、飽和度(Saturation)、明度(Value),又稱HSB(B即Brightness)。色相是色彩的基本屬性,就是平常說的顏色的名稱,如紅色、黃色等。飽和度(S)是指色彩的純度,越高色彩越純,低則逐漸變灰,取0-100%的數值。明度(V),取0-max(計算機中HSV取值範圍和儲存的長度有關)。HSV顏色空間可以用一個圓錐空間模型來描述。圓錐的頂點處,V=0,H和S無定義,代表黑色。圓錐的頂面中心處V=max,S=0,H無定義,代表白色。
在這裡插入圖片描述
注意:在opencv的HSV色彩空間中:H取值範圍是[0-179], S的取值範圍是[0-255], V的取值範圍是[0-255]

YUV色彩空間

  • 1、YUV(亦稱YCrCb)是被歐洲電視系統所採用的一種顏色編碼方法。在現代彩色電視系統中,通常採用三管彩色攝像機或彩色CCD攝影機進行取像,然後把取得的彩色影象訊號經分色、分別放大校正後得到RGB,再經過矩陣變換電路得到亮度訊號Y和兩個色差訊號R-Y(即U)、B-Y(即V),最後傳送端將亮度和兩個色差總共三個訊號分別進行編碼,用同一通道傳送出去。這種色彩的表示方法就是所謂的YUV色彩空間表示。採用YUV色彩空間的重要性是它的亮度訊號Y和色度訊號U、V是分離的。如果只有Y訊號分量而沒有U、V訊號分量,那麼這樣表示的影象就是黑白灰度影象。彩色電視採用YUV空間正是為了用亮度訊號Y解決彩色電視機與黑白電視機的相容問題,使黑白電視機也能接收彩色電視訊號。

  • 2、YUV主要用於優化彩色視訊訊號的傳輸,使其向後相容老式黑白電視。與RGB視訊訊號傳輸相比,它最大的優點在於只需佔用極少的頻寬(RGB要求三個獨立的視訊訊號同時傳輸)。其中“Y”表示明亮度(Luminance或Luma),也就是灰階值;而“U”和“V” 表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用於指定畫素的顏色。“亮度”是透過RGB輸入訊號來建立的,方法是將RGB訊號的特定部分疊加到一起。“色度”則定義了顏色的兩個方面─色調與飽和度,分別用Cr和Cb來表示。其中,Cr反映了RGB輸入訊號紅色部分與RGB訊號亮度值之間的差異。而Cb反映的是RGB輸入訊號藍色部分與RGB訊號亮度值之同的差異。

  • 3、YUV和RGB互相轉換的公式如下(RGB取值範圍均為0-255)︰
     Y = 0.299R + 0.587G + 0.114B
     U = -0.147R - 0.289G + 0.436B
     V = 0.615R - 0.515G - 0.100B
     R = Y + 1.14V
     G = Y - 0.39U - 0.58V
     B = Y + 2.03U

簡單的物體跟蹤示例

import cv2
import numpy as np

cap = cv2.VideoCapture(0)
while(1):
    # Take each frame
    _, frame = cap.read()
    # Convert BGR to HSV
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    # define range of blue color in HSV
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])
    # Threshold the HSV image to get only blue colors
    mask = cv2.inRange(hsv, lower_blue, upper_blue)
    # Bitwise-AND mask and original image
    res = cv2.bitwise_and(frame,frame, mask= mask)
    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break
cv2.destroyAllWindows()

在這裡插入圖片描述

HSV空間目標閾值選取

如何在HSV空間,跟蹤目標時選擇一個合適的閾值呢?辦法如下:
使用cv2.cvtColor函式,傳入一個BRG顏色值,flag引數為cv2.COLOR_BGR2HSV,函式的返回值就是此顏色在HSV空間的取值。示例如下:

green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print hsv_green
# [[[ 60 255 255]]]

那麼在HSV空間跟蹤此顏色的目標時,選取目標的顏色閾值可為: [H-10, 100,100] 到 [H+10, 255, 255]

影象幾何變換

影象的縮放操作主要包括縮小與放大、旋轉、仿射、投射等

影象的縮放

影象的縮放操作主要是函式:cv2.resize,函式原型如下:
cv2.resize(src,dsize,dst=None,fx=None,fy=None,interpolation=None)
關於此函式的詳細說明記錄在:python進階—OpenCV之常用影象操作函式說明
函式使用示例如下:

import cv2
import numpy as np

img = cv2.imread('messi5.jpg')
res = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)

height, width = img.shape[:2]
res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)

影象的位移

影象的旋轉要靠函式cv2.warpAffine完成,可以完成x或者y方向的上的移動
影象的移動操作需要一個2*3 的矩陣來指明x、y分別移動的畫素大小
矩陣格式為:M = [[1, 0, tx], [0, 1, ty]]
在這裡插入圖片描述
函式示例如下:

import cv2
import numpy as np

img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape

M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))

cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

在這裡插入圖片描述
注意:cv2.warpAffine此函式的地撒個引數是一個元組分別表示影象的寬、高:(width, height)
函式的詳細說明記錄在:python進階—OpenCV之常用影象操作函式說明

影象的旋轉

影象的旋轉要靠函式cv2.warpAffine完成,此函式可以將影象以指定的中心座標進行旋轉,此處既是影象的中心。
把影象以中心店旋轉一個角度,需要依靠一個2*3的旋轉矩陣,可以通過函式cv2.getRotationMatrix2D來獲得旋轉矩陣
在這裡插入圖片描述
在這裡插入圖片描述

img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape

M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
dst = cv2.warpAffine(img,M,(cols,rows))

在這裡插入圖片描述

影象的仿射

影象的仿射也是靠函式cv2.warpAffine完成,此函式可以將影象以指定的座標進行旋轉,
仿射操作也需要依靠一個2*3的旋轉矩陣,可以通過函式cv2.getAffineTransform來獲得旋轉矩陣

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('drawing.png')
rows,cols,ch = img.shape

pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])

M = cv2.getAffineTransform(pts1,pts2)

dst = cv2.warpAffine(img,M,(cols,rows))

plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

在這裡插入圖片描述
函式的詳細說明記錄在:python進階—OpenCV之常用影象操作函式說明

影象的投射

影象的仿射也是靠函式cv2.warpPerspective完成,此函式可以將影象以指定的座標進行旋轉,
投射操作也需要依靠一個3*3的旋轉矩陣,可以通過函式cv2.getPerspectiveTransform來獲得旋轉矩陣

img = cv2.imread('sudokusmall.png')
rows,cols,ch = img.shape

pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])

M = cv2.getPerspectiveTransform(pts1,pts2)

dst = cv2.warpPerspective(img,M,(300,300))

plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

在這裡插入圖片描述
函式的詳細說明記錄在:python進階—OpenCV之常用影象操作函式說明

影象閾值(二值化)

影象的簡單閾值二值化

cv.threshold實現影象的二值化操作,典型二值化操作如下

  • cv.THRESH_BINARY
  • cv.THRESH_BINARY_INV
  • cv.THRESH_TRUNC
  • cv.THRESH_TOZERO
  • cv.THRESH_TOZERO_INV

示例程式碼如下:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('gradient.png',0)
ret,thresh1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
ret,thresh2 = cv.threshold(img,127,255,cv.THRESH_BINARY_INV)
ret,thresh3 = cv.threshold(img,127,255,cv.THRESH_TRUNC)
ret,thresh4 = cv.threshold(img,127,255,cv.THRESH_TOZERO)
ret,thresh5 = cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in xrange(6):
    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
plt.show()

在這裡插入圖片描述
函式的詳細說明記錄在:python進階—OpenCV之常用影象操作函式說明

影象的自適應閾值二值化

cv.adaptiveThreshold函式實現自適應閾值二值化
自適應閾值計算方式有如下兩種

  • cv.ADAPTIVE_THRESH_MEAN_C : 鄰近閾值計算
  • cv.ADAPTIVE_THRESH_GAUSSIAN_C : 高斯鄰近閾值計算
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('sudoku.png',0)
img = cv.medianBlur(img,5)
ret,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
th2 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_MEAN_C,\
            cv.THRESH_BINARY,11,2)
th3 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,\
            cv.THRESH_BINARY,11,2)
titles = ['Original Image', 'Global Thresholding (v = 127)',
            'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]
for i in xrange(4):
    plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
plt.show()

在這裡插入圖片描述
函式的詳細說明記錄在:python進階—OpenCV之常用影象操作函式說明

Otsu’s二值化

當在函式cv.threshold函式的第4箱引數flag中使用cv.THRESH_OTSU標識時,表示使用Otsu’s二值化方式,即對那些在灰度影象的直方圖中具有明顯2個波峰的影象比較合適。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('noisy2.png',0)
# global thresholding
ret1,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
# Otsu's thresholding
ret2,th2 = cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
# Otsu's thresholding after Gaussian filtering
blur = cv.GaussianBlur(img,(5,5),0)
ret3,th3 = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
# plot all the images and their histograms
images = [img, 0, th1,
          img, 0, th2,
          blur, 0, th3]
titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)',
          'Original Noisy Image','Histogram',"Otsu's Thresholding",
          'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]
for i in xrange(3):
    plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')
    plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])
    plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)
    plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])
    plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')
    plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
plt.show()

在這裡插入圖片描述

影象模糊操作

模糊操作使用卷積計算實現的

均值模糊

均值模糊就是計算卷積核對應所有畫素的平均值,然後用平均值替換卷積核中心對應的畫素值
典型均值卷積核如下圖:

  • 函式原型:dst = cv.blur( src, ksize[, dst[, anchor[, borderType]]] )
  • src:輸入影象,通道數任意,每個通道會獨立處理,但是影象的深度depth只能是 CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
  • dst:輸出影象,大小與輸入影象一致
  • ksize:卷積核大小
  • anchor:卷積核中心點預設值是 Point(-1,-1) 表示卷積核的正中心與進行處理的畫素重合的點
  • borderType:邊沿模式
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('opencv-logo-white.png')
blur = cv.blur(img,(5,5))
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

以上程式碼中blur函式的ksize引數對應的卷積核如下圖:
在這裡插入圖片描述
在這裡插入圖片描述

中值模糊

中值模糊就是取卷積核對應所有畫素的中值,然後用此中值替換卷積核中心對應的畫素值
中值模糊只能定義卷積核的大小,內容不能自定義,卷積核的方式與均值模糊的卷積核相同
中值模糊適合去除椒鹽類影象噪點

  • 函式原型:dst = cv.medianBlur( src, ksize[, dst] )
  • src:輸入影象,影象為1、3、4通道的影象,當模板尺寸為3或5時,影象深度只能為CV_8U、CV_16U、CV_32F中的一個,如而對於較大尺寸的圖片,影象深度只能是CV_8U
  • dst:出影象,尺寸和型別與輸入影象一致
  • ksize:卷積核大小,也叫濾波模板的尺寸大小,必須是大於1的奇數,如3、5、7……
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('opencv-logo-white.png')
median = cv.medianBlur(img,5)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(median),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

在這裡插入圖片描述

自定義模糊

所謂自定義模糊就是,自定義卷積核,即可實現自定義模糊

  • 函式原型:dst = cv.filter2D( src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]] )
  • src:輸入影象
  • dst:輸出影象,和輸入影象具有相同的尺寸和通道數量
  • ddepth:目標影象深度,如果沒寫將生成與原影象深度相同的影象。當ddepth輸入值為-1時,目標影象和原影象深度保持一致。
  • kernel:卷積核(或者是相關核),一個單通道浮點型矩陣。如果想在影象不同的通道使用不同的kernel,可以先使用split()函式將影象通道事先分開。
  • anchor:卷積核的基準點(anchor),其預設值為(-1,-1)表示位於kernel中心位置。基準點即選取的kernel中心位置與進行處理畫素重合的點。
  • delta:在儲存目標影象前可選的新增到畫素的值,預設值為0
  • borderType:影象邊界逼近模式,預設值是BORDER_DEFAULT,即對全部邊界進行計算
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('opencv_logo.png')
kernel = np.ones((5,5),np.float32)/25
dst 
            
           

相關推薦

pythonOpenCV影象處理

文章目錄 顏色空間轉換 RGB色彩空間 HSV色彩空間 YUV色彩空間 簡單的物體跟蹤示例 HSV空間目標閾值選取 影象幾何變換 影象的縮放 影象的位移 影象的旋轉 影

pythonOpenCV影象處理

文章目錄 影象形態變換 影象的腐蝕 影象的膨脹 影象的開操作 影象的閉操作 影象的形態學梯度 影象的頂帽操作 影象的黑帽操作 影象的梯度(Image Gradients) So

OpenCV數字影象處理——直方圖均衡化的實現

計算一幅影象的直方圖 影象是由不同數值的顏色畫素組成,畫素值在整幅影象中的分佈情況是該影象的一個重要屬性。直方圖(Histogram)是一幅影象分佈的精確圖形表示。因此,灰度影象的直方圖有256個專案。 OpenCV計算直方圖 環境:Windows 10,

opencv+Python影象處理教程學習總結記錄

教程:2 opencv+python影象處理進階 講解老師:賈志剛 1.1 進階主要內容概述:影象卷積與應用,直方圖應用,模板匹配,影象金字塔 1.2 模糊與卷積原理 上圖顯示為一維和二維的均值卷積示例 相關Api : blur 程式碼示例 import c

pythonOpenCV常用影象操作函式說明

文章目錄 cv2.threshold cv2.bitwise_and cv2.bitwise_or cv2.bitwise_not cv2.inRange cv2.resize cv2.adaptiveThreshold cv2

Python——OpenCVCore Operations

文章目錄 影象基本操作 訪問並修改畫素值 訪問影象的屬性 設定影象區域 影象分割與合併 畫影象邊框 影象的數學操作 影象疊加 影象融合 影象位操作 Python

Python——OpenCVGUI

文章目錄 影象處理(Getting Started with Images) 讀取影象 顯示影象 儲存影象 使用Matplotlib 視訊處理(Getting Started with Videos)

python+OpenCV影象處理讀取、複製、顯示、儲存

前 言       從2017年入坑人工智慧領域開始,就被這一領域深深的所吸引,雖然到現在已經踩了不少坑,但總算有了不少的收穫,深感不虛此行,藉助強大的python讓我快速的向著這一領域靠近,現在流行比較廣的人工智慧應用,比如:影象識別,語音識別,文字情感分析,人體行為分析等

OpenCV入門教程十】 形態學影象處理:膨脹與腐蝕

本系列文章由@淺墨_毛星雲 出品,轉載請註明出處。 寫作當前博文時配套使用的OpenCV版本: 2.4.8本篇文章中,我們一起探究了影象處理中,最基本的形態學運算——膨脹與腐蝕。淺墨在文章開頭友情提醒,用人物照片做腐蝕和膨脹的素材圖片得到的效果會比較驚悚,毀三觀的,不建議嘗試

Python+OpenCV圖像處理——讀取顯示張圖片

沒有 class 釋放資源 圖像 Coding 路徑 troy 如果 nco   配置好所有環境後,開始利用python+opencv進行圖像處理第一步。   讀取和顯示一張圖片: import cv2 as cv src=cv.imread(‘E:\imageload\

python+opencv圖像處理

strong dct變換 mage uid 操作系統 之間 mea numpy 包括 一、什麽是opencv?     Open Source Computer Vision Library.OpenCV於1999年由Intel建立,如今由Willow Garage提供支持

opencv影象處理:讀取圖片,裁剪圖片

1.利用opencv讀取圖片: # -*- coding: utf-8 -*- # !/usr/bin/env python # @Time : 2018/11/19 14:59 # @Author : xhh # @Desc : 讀取圖片 # @File : open

【小白的Struts2系列1】---Struts2框架簡介

首先在此之前應該解決幾個問題: 什麼是框架?(Framework) 框架可以類比於建築中的房樑,可以說它是一個框子(指其約束性),也能說它是一個架子(指其支撐性) 約束性:針對解決特定的問題的軟體框架會首先定義問題的邊界,進而將相關的軟體組織約束在這個邊界內,保持框架在解決

Android2 陰影製作Shadow

dx:X軸方向的偏移量dy:Y軸方向的偏移量color:陰影顏色注意:如果半徑被設定為0,意思就是去掉陰影。具體實現:package xiaosi.textShadow;import android.app.Activity;import android.content.Context;import andr

十二vue.js元件——元件通訊3

(1)概述 所謂元件間的通訊,實際上就是指在各個元件間,進行引數或者資訊的相互傳遞。比如我們前面學的通過props給子元件傳參,實際上這就是父元件向子元件進行單向的通訊。 (2)元件間通訊的幾種方式 1.父到子的通訊 父到子的通訊使用我們前面使用的props即可

OpenCV嵌入式影象處理第一個OpenCV程式

在裝完了OpenCV和CUDA之後很自然的事情就是先跑個程式看看庫函式是否安裝完畢。對於在Windows下習慣用Visual Studio的同志們來說,可能很多人還不知道可以不用IDE程式設計(至少我當年轉Linux的時候就在想,用記事本寫程式,那工程檔案去哪了

執行緒:多工處理17——Java中的鎖Unsafe基礎

1. 概述 本專題在之前的文章中詳細介紹了Java中最常使用的一種鎖機制——同步鎖。但是同步鎖肯定是不適合在所有應用場景中使用的。所以從本文開始,筆者將試圖通過兩到三篇文章的篇幅向讀者介紹Java中鎖的分類、原理和底層實現。以便大家在實際工作中根據應用場景進行

python-教程-多個字典對映的合併

0.摘要 當我們處理多個字典(或稱為對映,因為字典是Python中唯一的對映結構),可以通過將多個字典合併為一個字典的方式實現批量處理。   1.ChainMap類 a = {'x': 1, 'z': 3 } b = {'y':

Java ——— Java多執行緒程序和執行緒

引言 講到執行緒,不可避免的提到程序。而因為執行緒無法脫離程序單獨存在,那什麼是程序? 延伸閱讀,Java多執行緒系列文章 什麼是程序? 程序:具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的最小單位。 例如手機執行的眾多

計算機視覺與影象處理——卷積與opencv

VideoCapture cap(0); //開啟預設攝像頭裝置 //1.VideoCapture cap(in device); 如果只有一個裝置,device只通過0