• Python-OpenCV API


    参考资料

    视频
    这些博客就是搭配上面那个视频使用的
    这篇也是这个视频的,这个比较齐
    参考1
    实例参考

    cv2.namedWindow

    详解
    在这里插入图片描述

    import cv2
    import numpy as np
    
    cv2.namedWindow('img', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('img', 600, 800)  # 自己设定窗口图片的大小
    img=cv2.imread("./pic/bank.png",0)#0表示灰度图方式读取图片 1表示以RGB方式读取 -1直接读取原图不做任何改变
    cv2.imshow('img', img)#显示在img这个窗体中
    
    img=cv2.imread("./pic/bank.png",1)#0表示灰度图方式读取图片 1表示以RGB方式读取,忽略alpha通道(默认) -1直接读取原图不做任何改变
    cv2.imshow('RGB', img)
    
    img=cv2.imread("./pic/bank.png",-1)#0表示灰度图方式读取图片 1表示以RGB方式读取 -1直接读取原图不做任何改变
    cv2.imshow('original drawing', img)
    
    cv2.waitKey(0)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    用微信截图功能就能看到bank的大小就是600×800
    在这里插入图片描述

    cv2.imread

    注意读取的图片不能是中文的 不然会报错
    cv2.imread(filepath,flags)
    1、参数说明:

    • filepath:要读入图片的完整路径
    • flags:读入图片的标志

    2、flag

    • cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道 1
    • cv2.IMREAD_GRAYSCALE:读入灰度图片 0
    • cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道 ** **

    alpha通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度复信息,定义透明、不透明和半透明区域,其中黑表示全透明,白表示不透明,灰表示半透明。

    import cv2
    import numpy as np
    
    cv2.namedWindow('img', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('img', 600, 800)  # 自己设定窗口图片的大小
    img=cv2.imread("./pic/bank.png",0)#0表示灰度图方式读取图片 1表示以RGB方式读取 -1直接读取原图不做任何改变
    cv2.imshow('img', img)#显示在img这个窗体中
    
    img=cv2.imread("./pic/bank.png",1)#0表示灰度图方式读取图片 1表示以RGB方式读取,忽略alpha通道(默认) -1直接读取原图不做任何改变
    cv2.imshow('RGB', img)
    
    img=cv2.imread("./pic/bank.png",-1)#0表示灰度图方式读取图片 1表示以RGB方式读取 -1直接读取原图不做任何改变
    cv2.imshow('original drawing', img)
    
    cv2.waitKey(0)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    用微信截图功能就能看到bank的大小就是600×800
    在这里插入图片描述

    cv2.cvtColor

    颜色转换

    cv2.cvtColor(input_image, flag)
    
    • 1
    • input_image:需要转换的图片
    • flag:转换类型,灰度cv2.COLOR_BGR2GRAY
    • 返回值:转换后的图片

    cv2.imshow()

    cv2.imShow()函数可以在窗口中显示图像。该窗口和图像的原始大小自适应(自动调整到原始尺寸)。

    • 第一个参数是一个窗口名称(也就是我们对话框的名称),它是一个字符串类型。
    • 第二个参数是我们的图像。
    • 您可以创建任意数量的窗口,但必须使用不同的窗口名称。

    在这里插入图片描述

    cv2.waitKey(0)

    • 是一个和键盘绑定的函数,它的作用是等待一个键盘的输入(因为我们创建的图片窗口如果没有这个函数的话会闪一下就消失了,所以如果需要让它持久输出,我们可以使用该函数)。
    • 它的参数是毫秒级。该函数等待任何键盘事件的指定毫秒。如果您在此期间按下任何键,程序将继续进行。我们也可以将其设置为一个特定的键。
    • 设置 waitKey(0) , 则表示程序会无限制的等待用户的按键事件(任意按键)

    cv2.destroyALLWindows()

    • 销毁我们创建的所有窗口。
    • 如果要销毁特定窗口,使用函数cv2.destroyWindow(),其中传递确切的窗口名称作为参数。(应该是使用创建窗口时所使用的窗口名称,字符串类型。)

    创建一个窗口,图片显示在其中

    先创建一个窗口,之后在需要的时候将图像加载到该窗口。

    def imshowing (img):
        cv2.namedWindow('img', cv2.WINDOW_NORMAL)#cv2.WINDOW_Normal,则可以调整窗口的大小。
        cv2.resizeWindow('img', 600,800)  # 自己设定窗口的大小 图片在其中显示 不会改变其像素个数
        cv2.imshow('img', img)
        print(img.shape)#元素个数
        cv2.waitKey(0)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    cv2.namedWindow()函数可以指定窗口是否可以调整大小。

    • 在默认情况下,标志为cv2.WINDOW_AUTOSIZE。
    • 但是,如果指定标志为cv2.WINDOW_Normal,则可以调整窗口的大小。

    cv2.imwrite

    详解
    函数 cv2.imwrite() 用于将图像保存到指定的文件。

    retval = cv2.imwrite(filename, img [, paras])
    
    • 1

    1、参数

    • filename:要保存的文件的路径和名称,包括文件扩展名
    • img:要保存的 OpenCV 图像,nparray 多维数组
    • paras:不同编码格式的参数,可选项(一般可以不填这项,如果要填的话可以看上面的详解,里面有详解)

    cv2.resize

    图片缩放

    cv2.resize(InputArray src, OutputArray dst, Size, fx, fy, interpolation)
    
    • 1

    1.输出尺寸格式为(宽,高)
    2.默认的插值方法为:双线性插值

    import cv2 as cv
    
    # 读入原图片
    img = cv.imread('./pic/bank.png')
    # 打印出图片尺寸
    print(img.shape)
    # 将图片高和宽分别赋值给x,y
    x, y = img.shape[0:2]
    
    # 显示原图
    cv.imshow('OriginalPicture', img)
    
    # 缩放到原来的二分之一,输出尺寸格式为(宽,高)
    img_test1 = cv.resize(img, (int(y / 2), int(x / 2)))
    cv.imshow('resize0', img_test1)
    
    
    # 最近邻插值法缩放
    # 缩放到原来的四分之一
    img_test2 = cv.resize(img, (0, 0), fx=0.25, fy=0.25, interpolation=cv.INTER_NEAREST)
    cv.imshow('resize1', img_test2)
    cv.waitKey()
    cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述
    注:如果要缩小图像,建议选择:cv2.INTER_AREA;如果要放大图像,cv2.INTER_CUBIC效果更好但是速度慢,cv2.INTER_LINEAR效果尚可且速度快。进行缩放时, dsize和fx、fy 二选一即可。
    在这里插入图片描述

    cv2.medianBlur

    中值滤波详解,里面有实例可以看下

    dst=cv2.medianBlur(src,ksize)

    • dst是返回值,表示进行中值滤波后得到的处理结果。
    • src 是需要处理的图像,即源图像。它能够有任意数量的通道,并能对各个通道独立处理。图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F中的一种。
    • ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中其邻域图像的高度和宽度。需要注意,核大小必须是比1大的奇数,比如3、5、7等。

    cv2.threshold()

    阈值的作用是根据设定的值处理图像的灰度值,比如灰度大于某个数值像素点保留。通过阈值以及有关算法可以实现从图像中抓取特定的图形,比如去除背景等。

    th,res=cv2.threshold (src, thresh, maxval, type)

    • src:源图片,必须是单通道
    • thresh:阈值,取值范围0~255
    • maxval:填充色,取值范围0~255
    • type:阈值类型,具体见下表
      在这里插入图片描述在这里插入图片描述
    • th:和thresh一样
    • res:经处理后的图片

    详解与示例

    cv2.findContours()轮廓检测

    详解

    binary, countours, hierarchy=cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])  
    
    • 1

    1、binary:寻找轮廓的图像
    2、mode:表示轮廓的检索模式,有四种:

    • cv2.RETR_EXTERNAL表示只检测外轮廓
    • cv2.RETR_LIST检测的轮廓不建立等级关系
    • cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
    • cv2.RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次。用这个就好了。说白了 这个就是将所有轮廓都存下来了,以后想用哪个就直接调就行了。

    3、method:为轮廓的近似(逼近)办法

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

    4、返回值

    • cv2.findContours()函数首先返回一个list,list中每个元素都是图像中的一个轮廓,用numpy中的ndarray表示。(新版已经没有这个返回值了,其实也用不到这个)
    • 轮廓本身
    • 每条轮廓对应的属性。

    5、注意点

    • 需要注意的是cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),所以读取的图像要先转成灰度的,再转成二值图
    • findcontours函数会“原地”修改输入的图像。这一点可通过下面的语句验证,执行这些语句后会发现原图被修改了。
    cv2.imshow("binary", binary)
    contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    cv2.imshow("binary2", binary)
    
    • 1
    • 2
    • 3
    • 新版只有两个返回值
      在这里插入图片描述
    import cv2
    
    def imshowing (img):
        cv2.namedWindow('img', cv2.WINDOW_NORMAL)
        cv2.resizeWindow('img', 545,408)  # 自己设定窗口图片的大小
        cv2.imshow('img', img)
        cv2.waitKey(0)
    
    img = cv2.imread('../pic/newxiaoyuan.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#灰度
    ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)#二值
    
    #cv2.RETR_TREE:将所有轮廓都存下来了,以后想用哪个就直接调就行了。
    contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    
    draw_img1=img.copy();#注意要用copy 不然draw是会在原图上操作 且会将其保存下来
    cv2.drawContours(draw_img1, contours, -1, (0, 0, 255), 3)#最后一个三就是线条的宽度
    imshowing(draw_img1)
    
    #算轮廓1的面积 与轮廓的周长
    draw_img2=img.copy()
    cv2.drawContours(draw_img2, contours,0 , (0, 0, 255), 3)#最后一个三就是线条的宽度
    imshowing(draw_img2)
    cnt=contours[0]
    print(cv2.contourArea(cnt))
    print(cv2.arcLength(cnt,True))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述
    在这里插入图片描述

    cv2.drawContours 轮廓的绘制

    cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])  
    
    • 1
    • image:指明在哪幅图像上绘制轮廓;
    • contours:轮廓本身,在Python中是一个list;
    • contourIdx:指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。
    • 后面的参数很简单。其中thickness表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。

    轮廓面积与周长

    cv2.contourArea()、cv2.arcLength()
    轮廓面积与周长

    //c#
    double cnt = Cv2.ContourArea(contours[i]);
    
    • 1
    • 2
    #算轮廓1的面积 与轮廓的周长
    draw_img2=img.copy()
    cv2.drawContours(draw_img2, contours,0 , (0, 0, 255), 3)#最后一个三就是线条的宽度
    imshowing(draw_img2)
    cnt=contours[0]
    print(cv2.contourArea(cnt))
    print(cv2.arcLength(cnt,True))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    cv2.minMaxLoc()

    求矩阵的最小值,最大值,并得到最大值,最小值的索引

    import numpy as np
    import cv2
    a=np.array([[1,2,3,4],[5,67,8,9]])
    min_val,max_val,min_indx,max_indx=cv2.minMaxLoc(a)
    
    print(min_val,max_val,min_indx,max_indx)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    out:

    1.0 67.0 (0, 0) (1, 1)
    
    • 1

    cv2.boundingRect

    使用boundingRect最好参数是二值图,这个方法确定是只能找到一个大框,不能分别画出各自的轮廓

    x, y, w, h = cv2.boundingRect(cnt)
    
    • 1
    • 用一个最小的矩形,把传递进来的东西给包起来。
    • cnt是一个轮廓点集合,也就是它的参数,可以通过cv2.findContours获取。或者是一个二值图
    • x,y是矩阵左上点的坐标,w,h是矩阵的宽和高

    在这里插入图片描述

    cv2.rectangle

    cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)画出矩形
    
    • 1
    • 和cv2.boundingRect配合着使用 一个找出来 一个画出来
    • 第一个参数:img是原图
    • 第二个参数:(x,y)是矩阵的左上点坐标
    • 第三个参数:(x+w,y+h)是矩阵的右下点坐标
    • 第四个参数:(0,255,0)是画线对应的rgb颜色
    • 第五个参数:2是所画的线的宽度
    import cv2
    import numpy as np
    
    #导入图片
    bgr_img = cv2.imread("./2.jpg")
    #再复制一张
    img=bgr_img.copy();
    #灰度
    gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)
    #二值化
    th, binary = cv2.threshold(gray_img, 0, 255, cv2.THRESH_OTSU)
    cv2.imshow('binary', binary)
    cv2.waitKey(0)
    #找到轮廓
    contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    #在bgr_img中将轮廓画出
    cv2.drawContours(bgr_img, contours, -1, (0, 0, 255), 3)
    cv2.imshow('bgr_img', bgr_img)
    cv2.waitKey(0)
    
    #找出将轮廓包住的最大矩形
    bounding_boxes = [cv2.boundingRect(cnt) for cnt in contours]
    #将每个轮廓包住的最大矩形画在bgr_img图中(这个图已经有被画好轮廓了)
    for bbox in bounding_boxes:
        [x, y, w, h] = bbox
        #这样应该就是一次循环画一个画出每一个
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
    cv2.imshow("finally", img)
    cv2.waitKey(0)
    
    # #直接传入二值图,能找到一个大框,但不能画出各自的轮廓
    # x,y,w,h =cv2.boundingRect(binary)
    # cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
    # cv2.imshow("finally", img)
    # cv2.waitKey(0)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    在这里插入图片描述
    在这里插入图片描述

    Mat.ptr

        cv::Mat image = cv::Mat(400, 600, CV_8UC1); //宽400,长600
        uchar * data00 = image.ptr<uchar>(0);
        uchar * data10 = image.ptr<uchar>(1);
        uchar * data01 = image.ptr<uchar>(0)[1];
    
    • 1
    • 2
    • 3
    • 4

    解释:

    • 定义了一个Mat变量image。
    • data00是指向image第一行第一个元素的指针。
    • data10是指向image第二行第一个元素的指针。
    • data01是指向image第一行第二个元素的指针。

    注意:

    • image.ptr(1);指的不是image中第二个像素,而是第一行第二个像素的指针。
    • 使用上面的代码举例:image有400行,有400*600个像素。假设现在你想得到第3行第42个像素的指针
    uchar * data = image.ptr<uchar>(3)[41];
    
    • 1

    实例

    #include
    #include
     
    using namespace cv;
    using namespace std;
     
    int main(int argc, char** argv)
    {
    	Mat src, gray,gray_clone;
    	src = imread("../../lena.jpg");
    	imshow("原图", src);
    	cvtColor(src, gray, CV_BGR2GRAY);
    	//复制一份灰度图
    	gray_clone = gray.clone();
    	imshow("灰度图", gray);
    
    
    	//原图画线
    	for(int i = 0;i<src.rows;i++)
    		for (int j = 0; j < src.cols; j++) {
    			uchar* p = src.ptr<uchar>(i, j);//具体某一个像素的指针
    			//原图是彩色图,操作三个通道修改颜色
    			if (i == j) {
    				p[0] = 0;
    				p[1] = 255;
    				p[2] = 255;
    			}
    		}
    	imshow("原图画线", src);
    	
    	
    	//灰度图画线方法1
    	double t1 = getTickCount();
    	for (int i = 0; i < gray.rows; i++)
    		for (int j = 0; j < gray.cols; j++) {
    			uchar* p = gray.ptr<uchar>(i, j);
    			//灰度图是单通道的,只需要操作一个通道即可
    			if (i == j) {
    				p[0] = 255;
    			}
    		}
    	double time_consume_1 = (getTickCount() - t1) / getTickFrequency();
    	printf("灰度图画线方法1耗时:%.3f\n", time_consume_1);
    	imshow("灰度图画线1", gray);
     
     
    	//灰度图画线方法2
    	double t2 = getTickCount();
    	for (int i = 0; i < gray_clone.rows; i++) {
    		uchar* p = gray_clone.ptr<uchar>(i);//这样写就是某一行
    		for (int j = 0; j < gray_clone.cols; j++) {
    			if (i == j)
    				p[j] = 255;//某一行的第j个
    		}
    	}
    	double time_consume_2 = (getTickCount() - t2) / getTickFrequency();
    	printf("灰度图画线方法2耗时:%.3f\n", time_consume_2);
    	imshow("灰度图画线2", gray_clone);
    	waitKey(0);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    在这里插入图片描述

    cv2.getStructuringElement

    详解
    在使用opencv的过程中,我们经常需要各种各样的卷积核。如果是正方形的核还好说,但是有时候需要定义椭圆形或者十字形的核,我们就需要用到cv2.getStructuringElement()函数了

    1、第一个参数表示核的形状。可以选择三种

    • 矩形:MORPH_RECT;
    • 交叉形:MORPH_CROSS;
    • 椭圆形:MORPH_ELLIPSE;

    2、第二个参数表示核的尺寸。

    cv2.erode

    参考

  • 相关阅读:
    (三) selenium元素定位和常用操作(下)
    Linux网络编程基础<多进程并发服务器>
    Spring 域对象共享数据
    element-ui 中 el-tree 和 el-table 样式调整
    2022年最新Python大数据之Python基础【六】函数与变量
    Vue ElementUI el-tooltip 全局样式修改
    每日一面系列之@Component和@Configuration区别
    paddlepaddle安装的问题
    C# 滑动验证码|拼图验证|SlideCaptcha
    .Net中Redis的Hash表操作
  • 原文地址:https://blog.csdn.net/chengcao123/article/details/127635255