内容纲要

  • cv::Mat
    • rows
    • cols
    • channels()
    • type()
    • colRange()
    • copyTo()
  • cv::Point
  • cv::Scalar

读写图像文件

  • imread()
  • imwrite()

文件存储

  • FileStorage

窗口展示

  • imshow()
  • namedWindow()
  • waitKey()
  • destroyWindow()
  • setMouseCallback()
  • createTrackbar()

视频

  • VideoCapture

直方图

  • equalizeHist() 均衡化直方图
  • calcHist() 计算直方图
  • calcBackProject() 反向投影
cv2.calcHist(images, channels, mask, histSize, ranges)
参数1:要计算的原图,以方括号的传入,如:[img]
参数2:类似前面提到的dims,灰度图写[0]就行,彩色图B/G/R分别传入[0]/[1]/[2]
参数3:要计算的区域,计算整幅图的话,写None
参数4:前面提到的bins
参数5:前面提到的range

滤波

  • boxFilter() 方框滤波
  • blur() 均值滤波
  • medianBlur() 中值滤波
  • GaussianBlur() 高斯滤波
  • bilateralFilter() 双边滤波
  • pyrMeanShiftFiltering()
// 方框滤波
Mat out; 
boxFilter(image, out, -1, Size(5, 5)); 
// 均值滤波
Mat dstImage; 
blur(srcImage, dstImage, Size(7, 7)); 
// 中值滤波
Mat out; 
medianBlur(image, out, 7);
// 高斯滤波
Mat out; 
GaussianBlur(image, out, Size(5, 5), 0, 0); 
// 双边滤波
Mat out; 
bilateralFilter(image, out, 25, 25*2, 25/2);
blurred = cv.pyrMeanShiftFiltering(image, 10, 100)  # 先均值迁移去噪声

颜色空间

  • cvtColor() 转换颜色空间
  • inRange() 颜色区域 mask
hsv = cv.cvtColor(src2, cv.COLOR_BGR2HSV)
mask = cv.inRange(hsv, (35, 43, 46), (99, 255, 255))

处理

  • add() 叠加

  • addWeighted() 叠加,权重不一样

  • subtract()

  • bitwise_and() 与

  • bitwise_or() 或

  • bitwise_xor() 异或

  • bitwise_not() 非

  • split() 分离通道

  • merge() 合并通道

  • remap() 重映射

  • adaptiveThreshold()

  • transpose()

  • Laplacian()

remap( srcImage, dstImage, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) );

二值化(阈值)

  • threshold() 二值化
    • THRESH_BINARY
  • adaptiveThreshold()
cvtColor( g_srcImage, g_grayImage, COLOR_RGB2GRAY );
threshold(g_grayImage, g_dstImage, g_nThresholdValue, 255, g_nThresholdType);
# 自动阈值分割 OTSU
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
# 自动阈值分割 TRIANGLE
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 25, 10)

做一些计算,其实在图像二值化的时候,我们需要考虑下面的因素,二值化方法选择:

  • 全局阈值二值化
  • 基于形态学梯度二值化
  • inRange二值化
  • 基于Canny边缘二值化
  • 自适应二值化

二值化后再进行形态学操作,连通区域,再查找轮廓。

缩放

  • resize() 缩放
    • INTER_LINEAR
    • INTER_NEAREST
    • INTER_CUBIC
    • INTER_LANCZOS4
  • pyrUp() 放大
  • pyrDown() 缩小
  • normalize() 图像像素归一化
    • NORM_MINMAX
    • NORM_INF
    • NORM_L1
    • NORM_L2
  • flip() 翻转
    • 0 倒影
    • 1 镜像
    • -1 对角
// 缩放
resize(tmpImage, dstImage1, Size(tmpImage.cols/2, tmpImage.rows/2), (0,0), (0,0), 3);
// 放大
pyrUp(tmpImage, dstImage, Size(tmpImage.cols*2, tmpImage.rows*2));
// 缩小
pyrDown(tmpImage, dstImage, Size(tmpImage.cols/2, tmpImage.rows/2));
dst = np.zeros(gray.shape, dtype=np.float32)
cv.normalize(gray, dst=dst, alpha=0, beta=1.0, norm_type=cv.NORM_MINMAX)

仿射变换

  • warpAffine()

形态学

  • eroded() 腐蚀
  • dilate() 膨胀
  • morphologyEx()
    • MORPH_ERODE 腐蚀
    • MORPH_DILATE 膨胀
    • MORPH_CLOSE 闭运算
    • MORPH_OPEN 开运算
    • MORPH_GRADIENT 梯度运算
    • MORPH_BLACKHAT 黑帽
    • MORPH_TOPHAT 顶帽
// 腐蚀
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat dstImage;
erode(srcImage, dstImage, element);
// 膨胀
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat out;
dilate(image, out, element);
// 腐蚀
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
morphologyEx(image, image, MORPH_ERODE, element);
// 膨胀
morphologyEx(image, image, MORPH_DILATE, element);
// 开运算
morphologyEx(image, image, MORPH_OPEN, element);
morphologyEx(image, image, MORPH_CLOSE, element);
morphologyEx(image, image, MORPH_GRADIENT, element);
morphologyEx(image, image, MORPH_BLACKHAT, element);
morphologyEx(image, image, MORPH_TOPHAT, element);

轮廓

  • findContours() 查找轮廓
  • drawContours() 绘制轮廓
  • approxPolyDP()
  • convexHull() 凸包检测
  • boundingRect() 外接矩形
  • minAreaRect() 最小外接矩形
  • minEnclosingCircle() 最小外接圆
  • fitEllipse() 拟合椭圆
  • moments() 轮廓的矩
  • watershed() 分水岭算法
  • contourArea() 轮廓面积
  • arcLength() 轮廓周长
  • matchShapes() 形状匹配

findContours

cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])

返回两个值:contours:hierarchy。

参数
第一个参数是寻找轮廓的图像;

第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):

cv2.RETR_EXTERNAL表示只检测外轮廓
cv2.RETR_LIST检测的轮廓不建立等级关系
cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
cv2.RETR_TREE建立一个等级树结构的轮廓。

第三个参数method为轮廓的近似办法

cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法

返回值
cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。

// 查找轮廓
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

findContours( srcImage, contours, hierarchy,RETR_CCOMP, CHAIN_APPROX_SIMPLE );

int index = 0;
for( ; index >= 0; index = hierarchy[index][0] )
{
    Scalar color( rand()&255, rand()&255, rand()&255 );
    drawContours( dstImage, contours, index, color, FILLED, 8, hierarchy );
}
// 凸包检测
vector<Point> points; 

for(int i = 0; i < count; i++ )
{
    Point point;
    point.x = rng.uniform(image.cols/4, image.cols*3/4);
    point.y = rng.uniform(image.rows/4, image.rows*3/4);

    points.push_back(point);
}

vector<int> hull;
convexHull(Mat(points), hull, true);
// 最小矩形包围
for(int  i = 0; i < count; i++ )
{
    Point point;
    point.x = rng.uniform(image.cols/4, image.cols*3/4);
    point.y = rng.uniform(image.rows/4, image.rows*3/4);

    points.push_back(point);
}

RotatedRect box = minAreaRect(Mat(points));
Point2f vertex[4];
box.points(vertex);
// 最小圆包围
vector<Point> points;

for(int  i = 0; i < count; i++ )
{
    Point point;
    point.x = rng.uniform(image.cols/4, image.cols*3/4);
    point.y = rng.uniform(image.rows/4, image.rows*3/4);

    points.push_back(point);
}

Point2f center;
float radius = 0;
minEnclosingCircle(Mat(points), center, radius);
# 轮廓发现
out, contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for c in range(len(contours)):
    # x, y, w, h = cv.boundingRect(contours[c]);
    # cv.drawContours(src, contours, c, (0, 0, 255), 2, 8)
    # cv.rectangle(src, (x, y), (x+w, y+h), (0, 0, 255), 1, 8, 0);
    rect = cv.minAreaRect(contours[c])
    cx, cy = rect[0]
    box = cv.boxPoints(rect)
    box = np.int0(box)
    cv.drawContours(src,[box],0,(0,0,255),2)
    cv.circle(src, (np.int32(cx), np.int32(cy)), 2, (255, 0, 0), 2, 8, 0)
def thresh_callback(thresh):
    global contours
    edges = cv2.Canny(blur,thresh,thresh*2)
    drawing = np.zeros(img.shape,np.uint8)      # Image to draw the contours
    contours,hierarchy = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    for cnt in contours:
        rect = cv2.minAreaRect(cnt)             # rect = ((center_x,center_y),(width,height),angle)
        points = cv2.cv.BoxPoints(rect)         # Find four vertices of rectangle from above rect
        points = np.int0(np.around(points))     # Round the values and make it integers

        ellipse = cv2.fitEllipse(cnt)           # ellipse = ((center),(width,height of bounding rect), angle)

        cv2.drawContours(drawing,[cnt],0,(0,255,0),2)   # draw contours in green color
        cv2.ellipse(drawing,ellipse,(0,0,255),2)        # draw ellipse in red color
        cv2.polylines(drawing,[points],True,(255,0,0),2)# draw rectangle in blue color

        cv2.imshow('output',drawing)
        cv2.imshow('input',img)
def main():  
    # 计算物体的周长、面积、质心、最小外接矩形等  
    # OpenCV函数:cv2.contourArea(), cv2.arcLength(), cv2.approxPolyDP()  
    # 等  
    # =================================寻找轮廓  
    img = cv2.imread('handwriting2.jpg', 0)  
    _, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)  
    image, contours, hierarchy = cv2.findContours(thresh, 3, 2)  
    # 以数字3的轮廓为例  
    cnt = contours[0]  

    # =================================轮廓面积  
    area = cv2.contourArea(cnt)  # 4386.5  
    print("area == " , area)  

    # =================================轮廓周长  
    perimeter = cv2.arcLength(cnt, True)  # 585.7  
    # 参数2表示轮廓是否封闭,显然我们的轮廓是封闭的,所以是True  
    print("perimeter == ", perimeter)  

    # =================================外接矩形  
    # 形状的外接矩形有两种,如下图,绿色的叫外接矩形,表示不考虑旋转并且能包含整个轮廓的矩形。  
    x, y, w, h = cv2.boundingRect(cnt)  # 外接矩形  
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)  
    # =================================# 最小外接矩形  
    rect = cv2.minAreaRect(cnt)  # 最小外接矩形  
    print(rect)  

    box = np.int0(cv2.boxPoints(rect))  # 矩形的四个角点取整  
    cv2.drawContours(img, [box], 0, (255, 0, 0), 2)  

    # =================================最小外接圆  
    (x, y), radius = cv2.minEnclosingCircle(cnt)  
    (x, y, radius) = np.int0((x, y, radius))  # 圆心和半径取整  
    cv2.circle(img, (x, y), radius, (0, 0, 255), 2)  

    # =================================拟合椭圆  
    ellipse = cv2.fitEllipse(cnt)  
    cv2.ellipse(img, ellipse, (255, 255, 0), 2)  

    # =================================形状匹配  
    img2 = cv2.imread('shapes.jpg', 0)  
    _, thresh = cv2.threshold(img2, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)  
    image, contours, hierarchy = cv2.findContours(thresh, 3, 2)  
    img_color = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)  # 用于绘制的彩色图  

    cnt_a, cnt_b, cnt_c = contours[0], contours[1], contours[2]  
    print(cv2.matchShapes(cnt_b, cnt_b, 1, 0.0))  # 0.0  
    print(cv2.matchShapes(cnt_b, cnt_c, 1, 0.0))  # 2.17e-05  
    print(cv2.matchShapes(cnt_b, cnt_a, 1, 0.0))  # 0.418  
    # matchShapes(contour1, contour2, method, parameter)  
    # 参数3是匹配方法,详情可参考:ShapeMatchModes,参数4是OpenCV的预留参数,暂时没有实现,  
    # 形状匹配是通过图像的Hu矩来实现的(cv2.HuMoments()),大家如果感兴趣,  

    # # cv2.imshow('thresh', thresh)  
    # # cv2.imshow('edges', edges)  
    cv2.imshow('img', img)  
    cv2.imshow('img2', img2)  
    cv2.waitKey(0)  

绘制

  • rectangle() 矩形
  • circle() 圆
  • ellipse() 椭圆
  • line()
  • polylines()
  • fitLine()
  • drawKeypoints()
  • drawMatches()
  • floodFill() 漫水填充
// 漫水填充
Rect ccomp;
floodFill(src, Point(50,300), Scalar(155, 255,55), &ccomp, Scalar(20, 20, 20), Scalar(20, 20, 20));

Canny

  • Canny()
Canny(edge, edge, 3, 9, 3);
# cv2.Canny()进行边缘检测,参数2、3表示最低、高阈值
edges = cv2.Canny(img, 30, 70)

Sobel

  • Sobel()
Sobel( src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT );

Laplacian

  • Laplacian()
Laplacian( src_gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT );

Scharr

Scharr( src, grad_x, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT );

Hough

  • HoughLines()
  • HoughLinesP()
  • HoughCircles()
vector<Vec2f> lines;
HoughLines(midImage, lines, 1, CV_PI/180, 150, 0, 0 );
vector<Vec4i> lines;
HoughLinesP(midImage, lines, 1, CV_PI/180, 80, 50, 10 );

Harris

  • cornerHarris()

Shi-Tomasi

  • goodFeaturesToTrack()

sift

orb

surf

模板匹配

  • matchTemplate()

发表评论

电子邮件地址不会被公开。 必填项已用*标注