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)

用微信截图功能就能看到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)

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

cv2.cvtColor

颜色转换

cv2.cvtColor(input_image, flag)
  • 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)

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

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

cv2.imwrite

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

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

1、参数

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

cv2.resize

图片缩放

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

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()

在这里插入图片描述
注:如果要缩小图像,建议选择: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、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)
  • 新版只有两个返回值
    在这里插入图片描述
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))

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

cv2.drawContours 轮廓的绘制

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

轮廓面积与周长

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

//c#
double cnt = Cv2.ContourArea(contours[i]);
#算轮廓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))

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)

out:

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

cv2.boundingRect

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

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

在这里插入图片描述

cv2.rectangle

cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)画出矩形
  • 和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)

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

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];

解释:

  • 定义了一个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];

实例

#include<opencv2/opencv.hpp>
#include<iostream>
 
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;
}

在这里插入图片描述

cv2.getStructuringElement

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

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

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

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

cv2.erode

参考

猜你喜欢

转载自blog.csdn.net/chengcao123/article/details/127635255