积分图&边缘检测

  • 一、积分图
  • 1.1 标准求和积分cv2.integral()
  • 1.2 平方和求积分cv2.integral2()
  • 1.3 倾斜求和积分cv2.integral3()
  • 二、Canny边缘检测cv2. Canny()


一、积分图

积分图是一种允许子区域内像素快速求和的数据结构。 opencv支持积分图的三种变体分别为:求和、平方求和、倾斜求和。每种情况的结果在图像的每个方向上都加1之后,与原始图像的大小相同。通过积分图,可以对图像的任意直立或倾斜的矩形区域的像素进行求和、平局以及标准差。并且计算复杂度控制为O(1)

opencv视频切分区域 opencv图像分块_opencv视频切分区域


  左:原图像灰度值。右:图像积分图

  求原图被20包围的矩形区域,398-9-10+1

1.1 标准求和积分cv2.integral()

sum= cv2. integral(src, sum=None, sdepth=None)

参数

含义

src

输入图像数组

sum

输出图像数组,如果输入图像的大小为W×H则输出图像的大小为(W+1)×(H+1)

sdepth

指明求和图像(结果图像)需要的深度,可以是cv2.S32、cv2.F64

import cv2
import numpy as np

filename = r'D:\Project\Opencv\Learning03\image03.png'
image = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
cv2.imshow('origin', image)

h, w = image.shape[:2]  # 把图片2像素的行数,列数以及通道数返回给rows,cols,channels
sum = np.zeros((h + 1, w + 1), dtype=np.float32)  # 创建指定大小的数组,数组元素以 0 来填充:

imageIntegral = cv2.integral(image, cv2.CV_32FC1)  # 计算积分图

result = np.zeros((h + 1, w + 1), dtype=np.uint8)
cv2.normalize(imageIntegral, result, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC1)  # 归一化处理
cv2.imshow("Image", result)
cv2.waitKey()

opencv视频切分区域 opencv图像分块_计算机视觉_02

1.2 平方和求积分cv2.integral2()

sum,sdepth= cv2. integral2(src, sum=None, sqsum=None, sdepth=None, sqdepth=None)

参数

含义

src

输入图像数组

sum

标准求和,输出图像数组,如果输入图像的大小为W×H则输出图像的大小为(W+1)×(H+1)

sqsum

平方和,输出图像数组,如果输入图像的大小为W×H则输出图像的大小为(W+1)×(H+1)

sdepth

指明求和图像(结果图像)需要的深度,可以是cv2.S32、cv2.F64

1.3 倾斜求和积分cv2.integral3()

sum,sdepth,tilted= cv2. integral3(src, sum=None, sqsum=None, tilted=None, sdepth=None, sqdepth=None)

参数

含义

src

输入图像数组

sum

标准求和,输出图像数组,如果输入图像的大小为W×H则输出图像的大小为(W+1)×(H+1)

sqsum

平方和,输出图像数组,如果输入图像的大小为W×H则输出图像的大小为(W+1)×(H+1

tilted

附加参数,得到附加结果

sdepth

指明求和图像(结果图像)需要的深度,可以是cv2.S32、cv2.F64

二、Canny边缘检测cv2. Canny()

  在canny算法中,现在x,y方向上求一阶导数,然后将他们组合成4个方向上的导数。
  dst= cv2. Canny(image, threshold1, threshold2, apertureSize=None, L2gradient=None)

参数

含义

image

输入图像数组

threshold1

低阈值

threshold2

高阈值

apertureSize=None

算法调用sobel算子所用的aperture大小

edges=None

附加参数,得到附加结果

L2gradient=None

用于选择使用适当的L2范数‘正确’计算方向梯度,还是使用速度快但精度低的L1范数

canny算法使用了两个阈值,高阈值和低阈值,如果一个像素的梯度大于高阈值,就认定为边缘,如果一个像素的梯度小鱼低阈值则抛弃该像素(非边缘),如果一个像素的梯度介于低阈值和高阈值之间,只有当这个像素连接到一个高于高阈值的像素时,才认定为边缘,否者抛弃该像素(非边缘)。通常canny算法建议高低阈值比为2:1——3:1之间。
  canny算法要求输入为单通道图像,输出图像是灰度图(实际上是一副布尔图)

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
'''canny边缘提取'''

def canny_demo(image):
    # 1.高斯模糊:最后两个参数给定一个就可以自动求取另一个,所以只给其中一个赋值就可以
    blur=cv.GaussianBlur(image,(3,3),0)
    #2.灰度处理
    gray=cv.cvtColor(blur,cv.COLOR_BGR2GRAY)
    #3.求取梯度,也可以不用梯度,直接将灰度图传入cv.canny
    grad_x=cv.Sobel(gray,cv.CV_16SC1,1,0)
    grad_y = cv.Sobel(gray, cv.CV_16SC1, 0, 1)
    #4.求边缘
    edge_output=cv.Canny(grad_x,grad_y,50,150)#参数:x梯度,y梯度 ,低阈值,高阈值

    cv.imshow('canny-demo',edge_output)
    dst=cv.bitwise_and(image,image,mask=edge_output)
    cv.imshow('color edge',dst)


img=cv.imread(r'D:\Project\Opencv\Learning01\fang.png')
cv.imshow('origin',img)
canny_demo(img)
cv.waitKey(0)

opencv视频切分区域 opencv图像分块_算法_03