opencv - 1 - 初入門徑

Coder-Wang發表於2024-09-04

配置環境

1、 下載python
2、 下載pycharm
3、 利用pip安裝以下庫

pip install numpy
pip install matplotlib
pipinstall opencv-python-i https://pypi.tuna.tsinghua.edu.cn/simple

4、 測試環境

import cv2 as cv
print(cv.__version__)

讀取/寫入影像

1、只讀取

import numpy as np
import cv2 as cv

#載入彩色灰度影像
img = cv.imread('img/1.png',0)
cv.imshow('First img',img)
cv.waitKey(0)
cv.destroyAllWindows()
  • waitKey()會檢測按下了什麼按鍵,如果一直不按就會一直等待直到按下再繼續下面的程式,另外還可以返回按下按鍵的值,如esc代表27,也可以用ord('s')直接指代s按鍵。
  • cv.destroyAllWindows()只會破壞我們建立的所有視窗。如果要銷燬任何特定的視窗,請使用函式 cv.destroyWindow()在其中傳遞確切的視窗名稱作為引數。
    2、用matplotlib讀取opencv得到的img物件
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('img/1.png',0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])  # 隱藏 x 軸和 y 軸上的刻度值
plt.show()

2、讀取加寫入

import numpy as np
import cv2 as cv
img = cv.imread('img/1.png',0)
cv.imshow('image',img)
k = cv.waitKey(0)
if k == 27:         # 等待ESC退出
    cv.destroyAllWindows()
elif k == ord('s'): # 等待關鍵字,儲存和退出
    cv.imwrite('img/1.png',img)
    cv.destroyAllWindows()
  • cv.imwrite('img/1.png',img)中路徑和原來一致就是覆蓋,若不是就是建立一個新的圖片,如cv.imwrite('img/4.png',img)

讀取/寫入影片

1、讀取攝像頭

import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0) #傳入數字時表示哪個攝像頭,傳入影片路徑就是讀取影片
if not cap.isOpened():
    print("Cannot open camera")
	cap.release()
    exit()
while True:
    # 逐幀捕獲,ret表示是否讀取到這一幀,frame表示這一幀的影像
    ret, frame = cap.read()
    # 如果正確讀取幀,ret為True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
	# 上一步已經得到了幀的img,在下一步讀取之前,該位置可以對影像做一定處理,如翻轉,改顏色等等,此處嘗試翻轉
	
    cv.imshow('frame', gray)
    if cv.waitKey(1) == ord('q') or cv.waitKey(1) == 27:
        break
# 完成所有操作後,釋放捕獲器
cap.release()
cv.destroyAllWindows()

2、讀取影片
cap = cv.VideoCapture(0) 中
cv.VideoCapture()傳入數字時表示哪個攝像頭,傳入影片路徑就是讀取影片
所以只需要改成
cap = cv.VideoCapture("img/vtest.avi")
即可讀取影片

3、儲存影片
主要是根據需要建立特定的寫入器,然後在讀取到幀和顯示幀之間做一個幀處理然後儲存該幀影像

import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
# 定義編解碼器並建立VideoWriter物件
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640,  480))
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    frame = cv.flip(frame, 0)
    # 寫翻轉的框架
    out.write(frame)
    cv.imshow('frame', frame)
    if cv.waitKey(1) == ord('q'):
        break
# 完成工作後釋放所有內容
cap.release()
out.release()
cv.destroyAllWindows()

所以我們捕捉一個影片,一幀一幀地處理,我們想要儲存這個影片。對於影像,它非常簡單,只需使用 cv.imwrite()。這裡還需要做一些工作。

建立一個 VideoWriter 物件。我們應該指定輸出檔名(例如: output.avi)。然後我們應該指定 FourCC 程式碼(詳見下一段)。然後傳遞幀率的數量和幀大小。最後一個是顏色標誌。如果為 True,編碼器期望顏色幀,否則它與灰度幀一起工作。

FourCC:http://en.wikipedia.org/wiki/FourCC 是用於指定影片編解碼器的4位元組程式碼。可用程式碼列表可在fourcc.org中:http://www.fourcc.org/codecs.php 找到。它取決於平臺。遵循編解碼器對我來說效果很好。

在Fedora中:DIVX,XVID,MJPG,X264,WMV1,WMV2。(最好使用XVID。MJPG會生成大尺寸的影片。X264會生成非常小的尺寸的影片)
在Windows中:DIVX(尚待測試和新增)
在OSX中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。

繪製影像

主要需要學習函式有:

  • cv.line()
  • cv.circle()
  • cv.rectangle()
  • cv.ellipse()
  • cv.putText()

常見引數有:

  • img:您要繪製形狀的影像
  • color:形狀的顏色。對於BGR,將其作為元組傳遞,例如:(255,0,0)對於藍色。對於灰度,只需傳遞標量值即可(標量即就一個引數數字)。
  • 厚度:線或圓等的粗細。如果對閉合圖形(如圓)傳遞-1 ,它將填充形狀。預設厚度= 1
  • lineType:線的型別,是否為8連線線,抗鋸齒線等。預設情況下,為8連線線。cv.LINE_AA給出了抗鋸齒的線條,看起來非常適合曲線。

1、建立直線

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

# 建立黑色的影像
img = np.zeros((512,512,3), np.uint8)
# 繪製一條厚度為5的藍色對角線
cv.line(img,(0,0),(511,250),(255,0,0),5)
cv.imwrite("img/4.png",img)
cv.imshow("img",img)
cv.waitKey(0)
cv.destroyAllWindows()
  • np.zeros()可知img物件的本質就是numpy的陣列物件,現在是建立了一個512*512大小的影像,np.uint8指裡面每個元素的符號型別,是一種無符號整型。
  • cv.line()引數有:被繪製影像物件、起點、終點、顏色、厚度

2、繪製圓

cv.circle(img,(447,63), 63, (0,0,255), -1)

3、畫橢圓
要繪製橢圓,我們需要傳遞幾個引數。一個引數是中心位置(x,y)。下一個引數是軸長度(長軸長度,短軸長度)。angle是橢圓沿逆時針方向旋轉的角度。startAngle和endAngle表示從主軸沿順時針方向測量的橢圓弧的開始和結束。即給出0和360給出完整的橢圓。有關更多詳細資訊,請參閱cv.ellipse的文件。下面的示例在影像的中心繪製一個橢圓形。

cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)

4、畫多邊形
要繪製多邊形,首先需要頂點的座標。將這些點組成形狀為ROWSx1x2的陣列,其中ROWS是頂點數,並且其型別應為int32。在這裡,我們繪製了一個帶有四個頂點的黃色小多邊形。

pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255))

5、向影像新增文字
要將文字放入影像中,需要指定以下內容。 - 您要寫入的文字資料 - 您要放置它的位置座標(即資料開始的左下角)。 - 字型型別(檢查cv.putText文件以獲取受支援的字型) - 字型比例(指定字型大小) - 常規的內容,例如顏色,厚度,線條型別等。為了獲得更好的外觀,建議使用lineType = cv.LINE_AA。

我們將在白色影像上寫入OpenCV

font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)

畫筆繪製

本質上就是給特定視窗繫結事件返回函式,然後對事件返回函式進行特定的改造

import numpy as np
import cv2 as cv

def draw_circle(event,x,y,flags,param):
    if event == cv.EVENT_LBUTTONDOWN:
        cv.circle(img,(x,y),10,(255,0,0),-1)
img = np.zeros((512, 512, 3), np.uint8)
cv.namedWindow("image")
cv.setMouseCallback("image",draw_circle)
# 該函式給某個視窗設定特定函式,這就說明我們必需按照他的要求寫事件函式
while True:
    cv.imshow("image",img)
    if cv.waitKey(20) & 0xFF == 27:
        break
cv.destroyAllWindows()

更好的利用返回函式

drawing = False # 如果按下滑鼠,則為真
mode = True # 如果為真,繪製矩形。按 m 鍵可以切換到曲線
ix,iy = -1,-1
# 滑鼠回撥函式
def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode
    if event == cv.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy = x,y
    elif event == cv.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                cv.circle(img,(x,y),5,(0,0,255),-1)
    elif event == cv.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
        else:
            cv.circle(img,(x,y),5,(0,0,255),-1)

相關文章