OpenCV-Python入門 下

鼠標操作與響應(yīng)

  • 鼠標Callback函數(shù)


    Callback函數(shù).JPG
事件.JPG
  • 應(yīng)用:使用鼠標進行矩形繪制


    繪制矩形.JPG
b1 = cv.imread(r"..\dataset\Image\The_Witcher_Lover.jpg")
img = np.copy(b1)
x1 = -1
x2 = -1
y1 = -1
y2 = -1

def mouse_drawing(event, x, y, falgs, param):
    global x1, y1, x2, y2
    if event == cv.EVENT_LBUTTONDOWN:
        x1 = x
        y1 = y
    if event == cv.EVENT_MOUSEMOVE:
        if x1 < 0 or y1 < 0:
            return
        x2 = x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 and dy > 0:
            b1[:,:,:] = img[:,:,:]
            cv.rectangle(b1, (x1, y1), (x2, y2), (0, 0, 255), 2, 8, 0)
    if event == cv.EVENT_LBUTTONUP:
        x2 = x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 and dy > 0:
            b1[:,:,:] = img[:,:,:]
            cv.rectangle(b1, (x1, y1), (x2, y2), (0, 0, 255), 2, 8, 0)
        x1 = -1
        x2 = -1
        y1 = -1
        y2 = -1

def mouse_demo():
    cv.namedWindow("mouse_demo", cv.WINDOW_AUTOSIZE)
    cv.setMouseCallback("mouse_demo", mouse_drawing)
    while True:
        cv.imshow("mouse_demo", b1)
        c = cv.waitKey(10)
        if c == 27:
            break
    cv.destroyAllWindows()

圖像像素類型轉(zhuǎn)換與歸一化

  • 歸一化方法支持


    歸一化.JPG
  • 歸一化函數(shù)

cv.normalize(src, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]] ) -> dst
src表示輸入圖像, dst表示輸出圖像,alpha, beta 默認是1, 0,是歸一化的區(qū)間值
norm_type默認是NORM_L2,norm_type常用是NORM_MINMAX

  • 注意:


    數(shù)據(jù)轉(zhuǎn)換.JPG
def norm_demo():
    image_uint8 = cv.imread(r"..\dataset\Image\The_Witcher_Lover.jpg")
    cv.imshow("input", image_uint8)
    img_f32 = np.float32(image_uint8)
    cv.imshow("imgf32", img_f32)
    cv.normalize(img_f32, img_f32, 1, 0, cv.NORM_MINMAX)
    cv.imshow("norm_imgf32", img_f32)
    cv.waitKey(0)
    cv.destroyAllWindows()

圖像幾何變換

幾何變換.JPG
  • 平移變換


    變換矩陣.JPG
  • 放縮變換


    放縮變換.JPG
  • 旋轉(zhuǎn)變換


    旋轉(zhuǎn)變換.JPG
  • 旋轉(zhuǎn)矩陣獲取函數(shù)

cv.getRotationMatrix2D
Center表示旋轉(zhuǎn)中心, angle表示度數(shù),大于零表示逆時針旋轉(zhuǎn), scale表示放縮尺度大小

  • 幾個旋轉(zhuǎn)操作函數(shù)

cv.flip(src, flipCode[, dst] ) ->dst
cv.rotate(src, rotateCode[, dst] ) -> dst
src表示輸入圖像
flipCode支持0水平、1垂直,-1對角線翻轉(zhuǎn),rotateCode支持旋轉(zhuǎn)90°,180°,270°

def affine_demo():
    image = cv.imread(r"..\dataset\Image\The_Witcher_Lover.jpg")
    h, w, c = image.shape
    cx = int(w / 2)
    cy = int(h / 2)
    cv.imshow("image", image)

    M = np.zeros((2, 3), dtype=np.float32)
    M[0, 0] = 3
    M[1, 1] = 3
    M[0, 2] = 0
    M[1, 2] = 0
    dst = cv.warpAffine(image, M, (int(w*3), int(h*3)))
    cv.imshow("rescale-demo", dst)

    M = cv.getRotationMatrix2D((w/2, h/2), 45.0, 1.0)
    dst = cv.warpAffine(image, M, (w, h))
    cv.imshow("rotate-demo", dst)

    dst = cv.flip(image, 0)
    cv.imshow("flip-demo", dst)

    cv.waitKey(0)
    cv.destroyAllWindows()

視頻讀寫處理

  • 視頻標準與格式

SD(Standard Definition)標清480P
HD(High Definition)高清720P/1080P
UHD(Ultra High Definition)超高清4K/2160P
分辨率表示
SD-640x480, 704x480, 720x480, 848x480等
HD-960x720,1280x720,1440x1080,1920x1080
UHD-4K,2160P

  • 視頻讀取函數(shù)


    視頻讀取.JPG
  • 視頻文件保存

cv.VideoWriter( filename, fource, fps, framesize[, isColor]-> <videoWriter object>
filename保存文件名稱,fourcc編碼方式,fps幀率,frameSize 視頻幀大小,與實現(xiàn)大小相符

  • 查詢視頻屬性


    查詢視頻屬性.JPG
def video_demo():
    cap = cv.VideoCapture("vtest.avi")
    # query video file metadata
    fps = cap.get(cv.CAP_PROP_FPS)
    frame_w = cap.get(cv.CAP_PROP_FRAME_WIDTH)
    frame_h = cap.get(cv.CAP_PROP_FRAME_HEIGHT)
    print(fps, frame_w, frame_h)
    # encode mode
    fourcc = cap.get(cv.CAP_PROP_FOURCC)
    # create video writer
    writer = cv.VideoWriter("output.mp4", int(fourcc), fps, (int(frame_w), int(frame_h)))
    # loop read frame until last frame
    while True:
        ret, frame = cap.read()
        if ret is not True:
            break
        cv.imshow("frame", frame)
        c = cv.witKey(1)
        if c == 27:
            break
        writer.write(frame)

圖像直方圖

  • 圖像直方圖函數(shù)

hist = cv.calcHist([image], [i], None, [32], [0, 256])
image輸入圖像,i表示通道索引,mask=None,histSize表示bin的個數(shù),表示通道的取值范圍0~256

def image_hist():
    image = cv.imread(r"..\dataset\Image\The_Witcher_Lover.jpg")
    cv.imshow("input", image)
    color = ('blue', 'green', 'red')
    for i, color in enumerate(color):
        hist = cv.calcHist([image], [i], None, [32], [0, 256])
        print(hist)
        plt.plot(hist, color=color)
        plt.xlim([0, 32])
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()

圖像直方圖均衡化

  • 直方圖均衡化原理


    直方圖均衡化.JPG
  • 直方圖均衡化函數(shù)

cv.equalizeHist(src[, dst]) -> dst
src必須是八位單通道圖像,dst返回結(jié)果圖像,類型與src保持一致

def eq_demo():
    image = cv.imread(r"..\dataset\Image\The_Witcher_Lover.jpg", cv.IMREAD_GRAYSCALE)
    cv.imshow("input", image)
    hist = cv.calcHist([image], [0], None, [32], [0, 256])
    print(hist.dtype)
    plt.plot(hist, color="gray")
    plt.xlim([0, 32])
    plt.show()
    cv.waitKey(0)

    eqimg = cv.equalizeHist(image)
    hist = cv.calcHist([eqimg], [0], None, [32], [0, 256])
    print(hist.dtype)
    plt.plot(hist, color="gray")
    plt.xlim([0, 32])
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()

圖像卷積操作

  • 圖像卷積的定義


    圖像卷積的定義.JPG
  • 卷積的邊緣填充

邊緣處理,邊緣填充的方式
cv.BORDER_DEFAULT gfedcb|abcdefgh|gfedcba
cv.BORDER_WRAP cdefgh|abcdefgh|abcdefg
cv.BORDER_CONSTANT iiiiii|abcdefgh|iiiiiii

  • 卷積模糊函數(shù)

v.blur( src, ksize[, dst[, anchor[, borderType]]]) -> dst
src表示輸入圖像 CV_8U, CV_32F or CV_64F
Ksize卷積核大小
Anchor錨定位置
borderType邊緣處理方式

def conv_demo():
    image = cv.imread("lena.png")
    dst = np.copy(image)
    cv.imshow("input", image)
    h, w, c = image.shape
    for row in range(1, h-1, 1):
        for col in range(1, w-1, 1):
            m = cv.mean(image[row-2 : row+2, col-2:col+2])
            dst[row, col] = (int(m[0]), int(m[1]), int(m[2]))
    cv.imshow("conv-demo", dst)

    blured = cv.blur(image, (5, 5), anchor=(-1, -1))
    cv.imshow("blur-demo", blured)

    cv.waitKey(0)
    cv.destroyAllWindows()

高斯模糊

  • 高斯模糊函數(shù)

cv.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) ->dst
ksize必須是正數(shù)而且是奇數(shù)
sigmaX高斯核函數(shù)X方向標準方差,sigmaY高斯核函數(shù)Y方向標準方差,默認0,表示跟sigmaX相同,
ksize為0表示從sigmaX計算生成ksize,ksize大于0表示從ksize計算生成sigmaX

  • 均值模糊與高斯模糊
    均值模糊 – 卷積核權(quán)重系數(shù)相同
    高斯模糊 – 卷積核根據(jù)高斯函數(shù)生成,權(quán)重系數(shù)不同
def conv_demo():
    image = cv.imread("lena.png")
    cv.imshow("input", image)

    g1 = cv.GaussianBlur(image, (0, 0), 15)
    g2 = cv.GaussianBlur(image, (15, 15), 15)
    cv.imshow("GaussianBlur-demo1", g1)
    cv.imshow("GaussianBlur-demo2", g2)

    cv.waitKey(0)
    cv.destroyAllWindows()

像素重映射

  • 像素重映射
    把像素點P(x,y)重新映射到一個新的位置P’(x’, y’)
  • 像素重映射函數(shù)

cv.remap(src, map1, map2, interpolation[, dst[, borderMode[, borderValue]]] ) -> dst
src表示圖像
map1表示x,y方向映射規(guī)則,或者x方向映射
map2如果map1表示x,y映射時為空,否則表示y
表示映射時候的像素插值方法,支持:INTER_NEAREST 、NTER_LINEAR 、NTER_CUBIC

def remap_demo():
    image = cv.imread("lena.png")
    cv.namedWindow("remap-demo", cv.WINDOW_AUTOSIZE)
    cv.createTrackbar("remap-type", "remap-demo", 0, 3, trackbar_callback)
    h, w, c = image.shape
    cv.imshow("input", image)
    map_x = np.zeros((h, w), dtype=np.float32)
    map_y = np.zeros((h, w), dtype=np.float32)
    while True:
        pos = cv.getTrackbarPos("remap-type", "remap-demo")
        #倒立
        if pos == 0:
            for i in range(map_x.shape[0]):
                map_x[i, :] = [x for x in range(map_x.shape[1])]
            for j in range(map_x.shape[1]):
                map_y[:, j] = [map_y.shape[0] - y for y in range(map_y.shape[0])]
        #鏡像
        elif pos == 1:
            for i in range(map_x.shape[0]):
                map_x[i, :] = [map_x.shape[1] - x for x in range(map_x.shape[1])]
            for j in range(map_x.shape[1]):
                map_y[:, j] = [y for y in range(map_y.shape[0])]
        #對角線對稱
        elif pos == 2:
            for i in range(map_x.shape[0]):
                map_x[i, :] = [map_x.shape[1] - x for x in range(map_x.shape[1])]
            for j in range(map_x.shape[1]):
                map_y[:, j] = [map_y.shape[0] - y for y in range(map_y.shape[0])]
        #放大兩倍
        elif pos == 3:
            for i in range(map_x.shape[0]):
                map_x[i, :] = [int(x/2) for x in range(map_x.shape[1])]
            for j in range(map_x.shape[1]):
                map_y[:, j] = [int(y/2) for y in range(map_y.shape[0])]

        dst = cv.remap(image, map_x, map_y, cv.INTER_LINEAR)
        cv.imshow("remap-demo", dst)
        c = cv.waitKey(100)
        if c == 27:
            break
    cv.waitKey(0)
    cv.destroyAllWindows()

圖像二值化

  • 圖像二值化的定義
    圖像二值化就是將圖像上的像素點的灰度值設(shè)置為0或255,也就是將整個圖像呈現(xiàn)出明顯的黑白效果的過程。圖像的二值化使圖像中數(shù)據(jù)量大為減少,從而能凸顯出目標的輪廓,是一種簡單的圖像分割方法。
    進行二值化有多種方式,其中最常用的就是采用閾值法(Thresholding)進行二值化。閾值法又分為全局閾值(Global Method)和局部閾值(Local Method),又稱自適應(yīng)閾值(Adaptive Thresholding)。


    圖像二值化定義.JPG
  • 二值化函數(shù)

cv.threshold( src, thresh, maxval, type[, dst]) -> retval, dst
src表示輸入圖像,thresh表示閾值,maxval表示最大值
type表示二值化THRESH_BINARY或者二值化反THRESH_BINARY_INV
retval表示返回閾值,dst返回的二值圖像

def binary_demo():
    #灰度圖像
    image = cv.imread(r"..\dataset\Image\The_Witcher_Lover.jpg")
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    cv.imshow("gray", gray)

    #手動閾值,二值化
    ret1, binary1 = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)
    cv.imshow("binary1", binary1)

    #求均值,二值化
    m = cv.mean(gray)[0]
    ret2, binary2 = cv.threshold(gray, m, 255, cv.THRESH_BINARY)
    cv.imshow("binary2", binary2)

    cv.waitKey(0)
    cv.destroyAllWindows()

全局與自適應(yīng)二值化

  • 全局二值化

OTSU法/大津法


全局二值化.JPG

三角法
圖像處理之三角法圖像二值化

cv.threshold( src, thresh, maxval, type[, dst])->retval, dst
type表示二值化
THRESH_BINARY | THRESH_OTSU
THRESH_BINARY | THRESH_TRIANGLE
THRESH_BINARY_INV | THRESH_OTSU
表示不同的全局二值化方法

  • 自適應(yīng)二值化

cv.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst] ) -> dst
cv.ADAPTIVE_THRESH_MEAN_C
cv.ADAPTIVE_THRESH_GAUSSIAN_C
blockSize必須為奇數(shù)
C表示要減去的權(quán)重,可以是正數(shù),負數(shù),0

def binary_demo():
    #灰度圖像
    image = cv.imread(r"..\dataset\Image\The_Witcher_Lover.jpg")
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    cv.imshow("gray", gray)

    #大津法,
    ret1, binary1 = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    cv.imshow("otsu", binary1)

    #三角法
    ret2, binary2 = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
    cv.imshow("triangle", binary2)

    # 自適應(yīng)法
    binary3 = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 25, 10)
    cv.imshow("adaptive", binary3)

    cv.waitKey(0)
    cv.destroyAllWindows()

實時人臉檢測

  • OpenCV3.3之前基于HAAR/LBP級聯(lián)檢測
    OpenCV3.3開始支持深度學習人臉檢測
    支持人臉檢測模型caffe/tensorflow
    OpenCV4.5.4 支持人臉檢測+landmark
    模型下載地址:https://gitee.com/opencv_ai/opencv_tutorial_data
  • 相關(guān)函數(shù)
    讀取模型:readNetFromTensorflow
    轉(zhuǎn)換為blob對象:blobFromImage
    設(shè)置輸入:setInput
    推理預(yù)測:forward
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容