天天看點

【持續更新】 | OpenCV 學習筆記第2章 處理檔案、攝像頭和圖形使用者界面第3章 使用OpenCV 3 處理圖像

本文位址:http://www.cnblogs.com/QingHuan/p/7365732.html,轉載請注明出處

###############################################################################

OpenCV的入門書籍有很多,這裡選擇的是《OpenCV 3計算機視覺-Python語言實作-第二版》

所有書上的源代碼:https://github.com/techfort/pycv

安裝過程請檢視我的另一篇部落格:

http://www.cnblogs.com/QingHuan/p/7354074.html

###############################################################################

第2章 處理檔案、攝像頭和圖形使用者界面

2.1 基本I/O腳本

2.1.5 捕獲攝像頭的幀

下面的代碼實作了捕獲攝像頭10秒的視訊資訊,并将其寫入一個AVI檔案中

1 import cv2
 2 
 3 cameraCapture = cv2.VideoCapture(0)
 4 fps = 30
 5 size = (int(cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)),
 6         int(cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
 7 videoWriter = cv2.VideoWriter(
 8     'MyOutputVid.avi', cv2.VideoWriter_fourcc('I', '4', '2', '0'),
 9     fps, size)
10 
11 success, frame = cameraCapture.read()
12 numFrameRemaining = 10*fps - 1
13 while success and numFrameRemaining > 0:
14     videoWriter.write(frame)
15     success, frame = cameraCapture.read()
16     numFrameRemaining -= 1
17 
18 cameraCapture.release()      

2.1.6 在視窗顯示圖像

一般情況下使用imshow()來顯示圖檔,圖檔會閃一下然後消失,下面代碼可以是圖檔一直顯示

1 import cv2
2 import numpy
3 
4 img = cv2.imread("data/aero1.jpg")
5 cv2.imshow('Test Image', img)
6 cv2.waitKey()
7 cv2.destroyAllWindows()      

雖然左上角沒有關閉按鈕,但是随便按一個按鍵,都會将其關閉

【持續更新】 | OpenCV 學習筆記第2章 處理檔案、攝像頭和圖形使用者界面第3章 使用OpenCV 3 處理圖像

2.1.7 實時顯示攝像頭的内容

1 import cv2
 2 import numpy
 3 
 4 clicked = False
 5 def onMouse(event, x, y, flags, param):
 6     global clicked
 7     if event == cv2.EVENT_FLAG_LBUTTON:
 8         clicked = True
 9 
10 cameraCapture = cv2.VideoCapture(0)
11 cv2.namedWindow('MyWindow')
12 cv2.setMouseCallback('MyWindow', onMouse)
13 
14 print 'Show camera feed. Click window or press any key to stop'
15 
16 success, frame = cameraCapture.read()
17 while success and cv2.waitKey(1) == -1 and not clicked:
18     cv2.imshow('MyWindow', frame)
19     success, frame = cameraCapture.read()
20 
21 cv2.destroyWindow('MyWindow')
22 cameraCapture.release()      

setMouseCallback可以擷取滑鼠的輸入

namedWindow()用來建立視窗

imshow()用來顯示視窗

destroyWindow()用來銷毀視窗

cameraCapture.release()用來釋放攝像頭

cv2.waitKey(1) == -1 :

參數為等待鍵盤觸發的時間,傳回值-1表示沒有按鍵被按下

OpenCV不能處理視窗,當單擊視窗的關閉按鈕時,并不能将其關閉

2.3  一個小程式—— Cameo——面向對象的設計

2.3.1 使用 managers.CaptureManager 提取視訊流

這裡中文版講的不太通順,建議看看英文原版

# CaptureManager 進階I/O流接口

import cv2
import numpy
import time



# 初始化CaptureManager類

class CaptureManager(object):

    def __init__(self, capture, previewWindowManager = None,
                 shouldMirrorPreview = False):

        # 更新:前面有下劃線的是非公有變量,主要與目前幀的狀态與檔案寫入操作有關
        # self 類似于結構體,裡面有很多變量,下面是在初始化這些變量
        # 類比于C++ 中學的"類"來比較
        self.previewWindowManager = previewWindowManager
        self.shouldMirrorPreview = shouldMirrorPreview

        self._capture = capture
        self._channel = 0
        self._enteredFrame = False
        self._frame = None
        self._imageFilename = None
        self._videoFilename = None
        self._videoEncoding = None
        self._videoWriter = None

        self._startTime = None
        self._frameElapsed = long(0)
        self._fpsEstimate = None

    # @ 符号的解釋參見:http://gohom.win/2015/10/25/pyDecorator/
    @property
    def channel(self):
        return self._channel

    @channel.setter
    def channel(self, value):
        if self._channel != value
            self._channel = value
            self._frame = None

    @property
    def frame(self):
        if self._enteredFrame and self._frame is None:
            _, self._frame = self._capture.retrieve()
        return self._frame

    @property
    def isWritingImage (self):
        return self._imageFilename is not None

    @property
    def isWrtingVideo(self):
        return self._videoFilename is not None

    def enterFrame(self):
        """Capture the next frame, if any"""      

View Code

暫停在書Page 30

代碼暫時寫到這裡,因為這裡根本不認真講原理,就是簡單的堆砌代碼,

感覺學習不到知識,是以就不看了,跳到下一章

第3章 使用OpenCV 3 處理圖像

3.2 傅立葉變換

下面是一個高通濾波器和低通濾波器的例子:注意看注釋,寫的很詳細

import cv2
import numpy as np
from scipy import ndimage

# kernel defined by ourself
kernel_3x3 = np.array([[-1, -1, -1],
                       [-1, 8, -1],
                       [-1, -1, -1]])

kernel_5x5 = np.array([[-1, -1, -1, -1, -1],
                       [-1, 1, 2, 1, -1],
                       [-1, 2, 4, 2, -1],
                       [-1, 1, 2, 1, -1],
                       [-1, -1, -1, -1, -1]])

# http://docs.opencv.org/3.1.0/d4/da8/group__imgcodecs.html
# in func "imread", 0 means trans to gray image
img = cv2.imread("data/lena.jpg", 0)

k3 = ndimage.convolve(img, kernel_3x3)
k5 = ndimage.convolve(img, kernel_5x5)

"""Gaussian kernel: The function convolves the source image
 with the specified Gaussian kernel. 
 
 GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) -> dst
 
 @param ksize Gaussian kernel size. ksize.width and ksize.height can differ but they both must be
    .   positive and odd. Or, they can be zero's and then they are computed from sigma.
 @param sigmaX Gaussian kernel standard deviation in X direction."""

# here is a per-defined Gaussian Blur and the
# kernel is set to 11x11, start in X axis direction
# Attention: GaussianBlur is a low pass filter but the above two are high pass filters
# after minus with the origin image, finally equivalent to a high pass filter
blurred = cv2.GaussianBlur(img, (11, 11), 0)
g_hpf = img - blurred

cv2.imshow("3x3", k3)
cv2.imshow("5x5", k5)
cv2.imshow("g_hpf", g_hpf)
cv2.waitKey()
cv2.destroyAllWindows()      

可以看一下處理效果:

原圖:

【持續更新】 | OpenCV 學習筆記第2章 處理檔案、攝像頭和圖形使用者界面第3章 使用OpenCV 3 處理圖像

高通濾波器:

3x3 kernel:

【持續更新】 | OpenCV 學習筆記第2章 處理檔案、攝像頭和圖形使用者界面第3章 使用OpenCV 3 處理圖像

5x5 kernel:

【持續更新】 | OpenCV 學習筆記第2章 處理檔案、攝像頭和圖形使用者界面第3章 使用OpenCV 3 處理圖像

用低通濾波器處理後的圖檔,與原圖相減,得到高通濾波器的效果:(原理待查)

【持續更新】 | OpenCV 學習筆記第2章 處理檔案、攝像頭和圖形使用者界面第3章 使用OpenCV 3 處理圖像

可以發現第三張圖的效果最好

中間都跳過去了,書上講的不好,是以隻是大概看了一遍沒有敲代碼

讀完這本書一定要換一本再補充一下

3.7 Canny 邊緣檢測

Canny函數可以非常友善的識别出邊緣,

例子如下:

import cv2
import numpy as np
import filters
from scipy import ndimage


img = cv2.imread("data/lena.jpg", 0)
cv2.imwrite("lena_edge.jpg", cv2.Canny(img, 200, 300))

cv2.imshow("lena", cv2.imread("lena_edge.jpg"))
cv2.waitKey()
cv2.destroyAllWindows()      

lena_edge.jpg:

【持續更新】 | OpenCV 學習筆記第2章 處理檔案、攝像頭和圖形使用者界面第3章 使用OpenCV 3 處理圖像

3.8 簡單的輪廓檢測

首先建立了一個黑色圖像,然後在中間放了一個白色方塊。然後對方塊尋找輪廓并把輪廓标注出來

(其實沒有看懂代碼)

# -*- coding: utf-8 -*
import cv2
import numpy as np
import filters
from scipy import ndimage

# dark, blank image
img = np.zeros((200, 200), dtype=np.uint8)
# assign the middle square white
img[50:150, 50:150] = 255

# 二值化
ret, thresh = cv2.threshold(img, 127, 255, 0)

image, contours, hierarchy = cv2.findContours(thresh,
                                              cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
color = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)

img = cv2.drawContours(color, contours, -1, (0, 255, 0), 2)

cv2.imshow("contours", color)
cv2.waitKey()
cv2.destroyAllWindows()      

結果:

【持續更新】 | OpenCV 學習筆記第2章 處理檔案、攝像頭和圖形使用者界面第3章 使用OpenCV 3 處理圖像

3.9 找到一個圖形的邊界框、最小矩形區域和最小閉圓的輪廓

# -*- coding: utf-8 -*
import cv2
import numpy as np

img = cv2.pyrDown(cv2.imread("pycv-master/chapter3/hammer.jpg", cv2.IMREAD_UNCHANGED))

ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) , 127, 255, cv2.THRESH_BINARY)
image, 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)

  # 畫一個正方形
  cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2)

  # 畫最貼近的正方形,有一定的旋轉
  # find minimum area
  rect = cv2.minAreaRect(c)
  # calculate coordinates of the minimum area rectangle
  box = cv2.boxPoints(rect)
  # normalize coordinates to integers
  box = np.int0(box)
  # 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()

cv2.imwrite("hammer_contours.jpg", img)      

結果:

【持續更新】 | OpenCV 學習筆記第2章 處理檔案、攝像頭和圖形使用者界面第3章 使用OpenCV 3 處理圖像

轉載于:https://www.cnblogs.com/QingHuan/p/7365732.html