opencv learn by 贾志刚

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

  1. 视频读取

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

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main() {
	VideoCapture cap;
	cap.open("D:/opencv/opencv/sources/samples/data/vtest.avi");
	if (!cap.isOpened())
		return -1;
	int width = cap.get(CV_CAP_PROP_FRAME_WIDTH);  // 宽度
	int height = cap.get(CV_CAP_PROP_FRAME_HEIGHT);// 高度
	int frameRate = cap.get(CV_CAP_PROP_FPS);          // 帧率
	int totalFrames = cap.get(CV_CAP_PROP_FRAME_COUNT);  // 帧数
	cout << "视频宽度=" << width << endl;
	cout << "视频高度=" << height << endl;
	cout << "视频帧率=" << frameRate << endl;
	cout << "视频帧数=" << totalFrames << endl;
	Mat frame,dst;
	while (1) {
		cap >> frame;
		if (frame.empty())
			break;
		//imshow("video", frame);
		Canny(frame, dst, 20, 180);
		imshow("video", dst);
		waitKey(20);
	}
	cap.release();
	return 0;
}

在这里插入图片描述

# 鼠标左键点下,画圆
#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;
void OnMouse(int event,int x,int y,int flags,void * param)
{
	Mat img = *(Mat*)param;
	if (event == CV_EVENT_LBUTTONDOWN)
	{
		cout << "Mouse down" << endl;
		circle(img, Point(x, y), 20, Scalar(255, 0, 0), 2, 8);
	}
}
int main() {
	Mat img(500,500,CV_8UC3,Scalar(255,255,255));
	namedWindow("Mouse", CV_WINDOW_AUTOSIZE);
	setMouseCallback("Mouse", OnMouse, &img);

	while(1) {
		imshow("Mouse", img);
		if (27 == waitKey(10))//安下Esc 退出
			break;
	}
	return 0;
}

# 鼠标左键拖动两个点,画矩形
#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;
Point pt;
void OnMouse(int event,int x,int y,int flags,void * param)
{
	Mat img = *(Mat*)param;
	switch(event)
	{
		case CV_EVENT_LBUTTONDOWN:
			pt.x = x;
			pt.y = y;
			break;
		case CV_EVENT_LBUTTONUP:
			rectangle(img, pt, Point(x, y), Scalar(255, 0, 0), 2, 8);
			break;
		default:
			break;
	}
}
int main() {
	Mat img(500,500,CV_8UC3,Scalar(255,255,255));
	namedWindow("Mouse", CV_WINDOW_AUTOSIZE);
	setMouseCallback("Mouse", OnMouse, &img);

	while(1) {
		imshow("Mouse", img);
		if (27 == waitKey(10))//安下Esc 退出
			break;
	}
	return 0;
}

在这里插入图片描述

# 调用canny算子进行边缘检测,滑动窗口改变的是canny算子的下限值
#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;
int value = 0;
void OnChange(int event,void * param)
{
	Mat src = *(Mat*)param,dst;

	//threshold(src, dst, value, 255, THRESH_BINARY);
	Canny(src, dst, value, 255);
	imshow("TrackBar", dst);

}
int main() {
	Mat src = imread("F:/12.jpg",0),dst;
	namedWindow("TrackBar",CV_WINDOW_AUTOSIZE);
	createTrackbar("Threshold","TrackBar",&value,255,OnChange,&src);
	threshold(src, dst, value, 255, THRESH_BINARY);
	imshow("TrackBar", dst);
	waitKey(0);
	return 0;
}

# 鼠标截图功能,读取图片,在图片中框选ROI区域,并将ROI区域重新保存为一张.bmp图片
#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;
Mat src = imread("F:/12.jpg", 1); // 读取图片
Point pt; //保存鼠标左键按下时的点
bool flag_1 = false; //当鼠标左键按下时,为真
Mat temp = src.clone(); //记录原图,用于后续刷新框图
Mat ROI;

// 鼠标消息回调函数
void OnMouse(int event,int x,int y,int flag,void * param)
{
	//Mat src = *(Mat*)param,dst;
	//Mat temp = src.clone();
	switch (event)
	{
	case CV_EVENT_LBUTTONDOWN: //鼠标左键按下
		flag_1 = true;
		pt.x = x;
		pt.y = y;
		break;
	case CV_EVENT_MOUSEMOVE: //鼠标移动
		if (flag_1)
		{
			temp.copyTo(src);
			rectangle(src, pt, Point(x, y), Scalar(0, 255, 0), 2, 8);
		}
		break;
	case CV_EVENT_LBUTTONUP: //鼠标左键抬起
		rectangle(src, pt, Point(x, y), Scalar(0, 255, 0), 2, 8);
		flag_1 = false;
		ROI = temp(Rect(pt.x, pt.y, x - pt.x, y - pt.y)); //确定ROI区域
		imshow("ROI", ROI);
		imwrite("ROI.bmp", ROI);
		break;
	default:
		break;
	}
}

int main() {
	//Mat src = imread("F:/12.jpg",1),dst;
	namedWindow("TrackBar",CV_WINDOW_AUTOSIZE);
	setMouseCallback("TrackBar",OnMouse,&src);
	while (1)
	{
		imshow("TrackBar", src);
		if (27 == waitKey(10))
			break;
	}
	
	return 0;
}

在这里插入图片描述

# 滑动条视频播放
#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;
double Fps;
int value = 0; //设置进度条时传递的参数,此时指从哪一帧开始
int framePos;
void OnChange(int,void* )
{

}
int main() {

	Mat frame;
	char strFps[20];
	
	VideoCapture cap("vtest.avi");
	int FrameCount = cap.get(CV_CAP_PROP_FRAME_COUNT); //获取视频总帧数
	Fps = cap.get(CV_CAP_PROP_FPS);  // 获取视频原始帧率
	if (!cap.isOpened()) //如果视频打开失败,则返回
		return -1;
	namedWindow("Video",CV_WINDOW_AUTOSIZE);
	createTrackbar("Frame", "Video", &value, FrameCount, OnChange, 0);


	
	sprintf_s(strFps,"Fps:%0.1lf/s", Fps);
	while (1)
	{
		framePos = cap.get(CV_CAP_PROP_POS_FRAMES);//获取视频当前帧
		setTrackbarPos("Frame","Video", framePos); //设置滑动条位置
		cap >> frame;
		if (frame.empty()) //图片读取为空,则结束
			break;
		putText(frame, strFps, Point(5, 30),CV_FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(0, 255, 0), 1, 8);
		imshow("Video", frame);
		if (27 == (int)waitKey(1000 / Fps)) // 按下Esc退出
			break;
	}
	cap.release();
	destroyAllWindows();
	return 0;
}

在这里插入图片描述

# 滑动条调节对比度和亮度
#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;
#define WIN_NAME "结果图"
int Contrase_Value = 20;  //对比度
int Bright_Value = 20;    //亮度
Mat src;
Mat dst;
void OnChange(int ,void*) 
{
	for (int i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			dst.at<Vec3b>(i,j)[0] = saturate_cast<uchar>(src.at<Vec3b>(i,j)[0] * 0.01*Contrase_Value + Bright_Value);
			dst.at<Vec3b>(i,j)[1] = saturate_cast<uchar>(src.at<Vec3b>(i,j)[1] * 0.01*Contrase_Value + Bright_Value);
			dst.at<Vec3b>(i,j)[2] = saturate_cast<uchar>(src.at<Vec3b>(i,j)[2] * 0.01*Contrase_Value + Bright_Value);
		}
	}
	imshow("原图", src);
	imshow(WIN_NAME, dst);
}
int main()
{
	src = imread("F:/12.jpg");
	dst=Mat::zeros(src.size(),src.type());  //以输入图像的大小和类型构建全零矩阵

	namedWindow(WIN_NAME,CV_WINDOW_AUTOSIZE);

	createTrackbar("对比度",WIN_NAME, &Contrase_Value,300,OnChange,0);
	createTrackbar("亮度",WIN_NAME, &Bright_Value,200,OnChange,0);
	OnChange(Contrase_Value,0);
	OnChange(Bright_Value,0);

	waitKey(0);
}

在这里插入图片描述

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat src;
	Mat dst;
	src = imread("F:/12.jpg");
	vector<Mat> channels;
	split(src, channels); //通道分离
	Mat bluechannel = channels.at(0);  //蓝色通道
	Mat greenchannel = channels.at(1); //绿色通道
	Mat redchannel = channels.at(2);   //红色通道
	threshold(bluechannel, bluechannel , 200, 255, THRESH_BINARY);
	threshold(greenchannel, greenchannel, 200, 255, THRESH_BINARY);
	threshold(redchannel, redchannel, 200, 255, THRESH_BINARY);
	//imshow("blue", bluechannel);
	//imshow("green", greenchannel);
	//imshow("red", redchannel);

	merge(channels, dst);  //合并通道
	imshow("dst",dst);

	waitKey(0);
}

在这里插入图片描述

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat src;
	Mat dst;
	src = imread("F:/12.jpg");
	Mat logo = imread("D:/opencv/opencv/sources/samples/data/opencv-logo.png");
	Mat mask = Mat::zeros(logo.size(),CV_8UC1); // 先创建一个纯黑图
	circle(mask, Point(mask.rows / 2, mask.cols / 2),100,Scalar(255),-1,8); // 画一个填充的半径为100的圆
	Mat imgRoi = src(Rect(20,3,logo.cols,logo.rows));//Rect方法定义,x,y,w,h
	//Mat imgRoi = src(Range(300,700),Range(200,1100));//Range方法定义
	logo.copyTo(imgRoi,mask);//将logo图片拷贝到img的ROI上(注意copyTo函数要求两图像大小和类型都相同,否则无效)
	//1、image.copyTo(imageROI),作用是把image的内容粘贴到imageROI;
	// 2、image.copyTo(imageROI,mask),作用是把mask和image重叠以后
	//把mask中像素值为0(black)的点对应的image中的点变为透明,而保留其他点。
	imshow("roi", src);
	//imwrite("saveRoi.png", imgRoi);//保存ROI图片
	waitKey(0);
}


在这里插入图片描述

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat src;
	Mat dst;
	src = imread("F:/12.jpg");
	Mat logo = imread("D:/opencv/opencv/sources/samples/data/opencv-logo.png");
	Mat mask = imread("D:/opencv/opencv/sources/samples/data/opencv-logo.png");
	bitwise_not(mask, mask); //将logo图片取反,因为logo图背景为白色,要变成掩码用的黑色,则需要取反
	threshold(mask, mask, 100, 255, THRESH_BINARY); // 利用二值化,将背景都直为0
	//Mat mask = Mat::zeros(logo.size(),CV_8UC1); // 先创建一个纯黑图
	//circle(mask, Point(mask.rows / 2, mask.cols / 2),100,Scalar(255),-1,8); // 画一个填充的半径为100的圆
	Mat imgRoi = src(Rect(20,3,logo.cols,logo.rows));//Rect方法定义,x,y,w,h
	//Mat imgRoi = src(Range(300,700),Range(200,1100));//Range方法定义
	logo.copyTo(imgRoi,mask);//将logo图片拷贝到img的ROI上(注意copyTo函数要求两图像大小和类型都相同,否则无效)
	//1、image.copyTo(imageROI),作用是把image的内容粘贴到imageROI;
	// 2、image.copyTo(imageROI,mask),作用是把mask和image重叠以后
	//把mask中像素值为0(black)的点对应的image中的点变为透明,而保留其他点。
	imshow("roi", src);
	//imwrite("saveRoi.png", imgRoi);//保存ROI图片
	waitKey(0);
}

在这里插入图片描述

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat src;
	Mat dst;
	src = imread("F:/12.jpg");
	//resize(src, dst, Size(500, 300)); // 通过Size参数设置图片大小
	resize(src, dst, Size(),0.5,0.5);  //通过比例系数设置图像大小,Size()设置为默认参数
	imshow("src", src);
	imshow("dst", dst);
	
	waitKey(0);
}

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

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat src;
	Mat dst;
	src = imread("F:/12.jpg");
	Point2f center = Point2f(src.rows / 2, src.cols / 2); //旋转中心
	double angle = 45;  //旋转角度
	double scale = 0.5; //缩放尺度
	Mat rotateMat;
	rotateMat = getRotationMatrix2D(center, angle, scale); //生成二维旋转矩阵
	Mat rotateImg;
	warpAffine(src, rotateImg, rotateMat, Size(1200, 900)); //调用仿射变换函数
	imshow("src", src);
	imshow("dst", rotateImg);
	
	waitKey(0);
}

在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat src;
	Mat dst1,dst2;
	src = imread("F:/12.jpg");
	Mat element = getStructuringElement(MORPH_RECT,Size(9,9));
	erode(src,dst1,element);   // 腐蚀
	dilate(src,dst2, element); // 膨胀
	imshow("src", src);
	imshow("腐蚀", dst1);
	imshow("膨胀", dst2);
	waitKey(0);
}

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

2. python

2.1 模糊操作

均值滤波 dst = blur(src,ksize,anchor=None,borderType=None)

-参数src表示输入图像
-参数dst 表示模糊之后输出对象
-参数ksize表示卷积核大小,此参数决定模糊程度,Size(x, y)其中x, y取值越大表现模糊程度越深,而且X与Y的值为奇数。
-参数anchor表示锚定的位置,也就是卷积核替换重叠像素中的哪个位置。此参数一般使用Point(-1,-1)表示使用卷积核的中心位置。
-最后一个参数borderType表示对边缘的处理方法,一般默认4表示默认处理方法

blurDst = cv2.blur(src,(3,3))
# (ncols, nrows)

高斯滤波dst = cv2.GaussianBlur(src,ksize,SigmaX,SigmaY=None,borderType=None);

-参数src表示输入图像
-参数dst 表示模糊之后输出对象
-参数ksize表示卷积核大小,此参数决定模糊程度,Size(x, y)其中x, y取值越大表现模糊程度越深,而且X与Y的值为奇数。
-参数SigmaX表示高斯方程中X方向的标准方差
-参数SigmaY表示高斯方程中X方向的标准方差
-最后一个参数表示对边缘的处理方法,一般默认4表示默认处理方法

blurDst = cv2.GaussianBlur(src,(3,3),11,11);
# (ncols, nrows)

中值滤波dst = cv2.medianBlur(src,ksize)

-参数src表示输入图像
-参数dst 表示模糊之后输出对象
-参数ksize表示卷积核大小,必须是正数而且必须是大于1,如:3、5、7等。

blurDst = cv2.medianBlur(src,(3,3))
# (ncols, nrows)

双边滤波dst = cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace,borderType=None)

-参数src表示输入图像
-参数dst 表示模糊之后输出对象
-参数d表示双边滤波时候中心到周围像素距离
-参数sigmaColor表示高斯核中颜色值标准方差
-参数sigmaSpace表示高斯核中空间的标准方差
-参数borderType表示边缘的处理方法

blurDst = cv2.bilateralFilter(src,15,120,10,4)
# (ncols, nrows)

均值偏移滤波dst=cv2.pyrMeanShiftFiltering( src, sp, sr, maxLevel=1, TermCriteria termcrit=TermCriteria( TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) );

src,输入图像
dst,输出图像
sp,定义的漂移物理空间半径大小
sr,定义的漂移色彩空间半径大小
maxLevel,定义金字塔的最大层数
termcrit,定义的漂移迭代终止条件,可以设置为迭代次数满足终止,迭代目标与中心点偏差满足终止,或者两者的结合

im = cv2.pyrMeanShiftFiltering(src, 10, 50)

滤波函数filter2D

-参数src表示输入图像
-参数dst表示模糊之后输出对象
-参数d表输出图像的深度,-1表示跟输入图像深度相同。
-参数kernel表示自定义的卷积核或者算子。
-参数anchor表示锚定的位置,Point(-1, -1)表示默认为卷积核中心位置。
-参数delta表示卷积处理之后的每个像素值是否加上常量delta,默认0.0表示不加上额外值到处理后的像素值上。
-参数borderType表示边缘像素的处理方式,默认为BORDER_DEFAULT。
通过定义不同的卷积核、filter2D函数可以实现卷积的各种功能、包括模糊、锐化、边缘提取等。

kernel = np.ones([3, 3], dtype=np.float32)/9
cv2.filter2D(src,-1,kernel);

3. 直方图统计

3.1 利用opencv自带函数

hist = cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]])

imaes:输入的图像
channels:选择图像的通道
mask:掩膜,是一个大小和image一样的np数组,其中把需要处理的部分指定为1,不需要处理的部分指定为0,一般设置为None,表示处理整幅图像
histSize:使用多少个bin(柱子),一般为256
ranges:像素值的范围,一般为[0,255]表示0~255
后面两个参数基本不用管。
注意,除了mask,其他四个参数都要带[]号。

img = cv2.imread('cat.jpg',0) #0表示灰度图
hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist.shape
#(256, 1)
# 统计每个通道的直方图
img = cv2.imread('cat.jpg') 
color = ('b','g','r')
for i,col in enumerate(color): 
    histr = cv2.calcHist([img],[i],None,[256],[0,256]) 
    plt.plot(histr,color = col) 
    plt.xlim([0,256]) 
plt.show()
# 在mask下统计直方图
# 创建mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255

img = cv2.imread('cat.jpg', 0)
masked_img = cv2.bitwise_and(img, img, mask=mask)#与操作

hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])

plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask, 'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
plt.xlim([0, 256])
plt.show()

3.2 利用matplotlib.pyplot 的函数

img = cv2.imread('clahe.jpg',0) #0表示灰度图
plt.hist(img.ravel(),256); 
plt.show()
equ = cv2.equalizeHist(img) # 直方图均衡化
plt.hist(equ.ravel(),256)
plt.show()

numpy中的ravel()、flatten()、squeeze()都有将多维数组转换为一维数组的功能,区别:
ravel():如果没有必要,不会产生源数据的副本
flatten():返回源数据的副本
squeeze():只能对维数为1的维度降维

3.3 局部自适应均衡化

全局的均衡化也会存在一些问题,由于整体亮度的提升,会使得局部图像的细节变得模糊;因此可以使用效果更好的自适应均衡化。

cv2.createCLAHA(clipLimit=8.0, titleGridSize=(8, 8)) 用于生成自适应均衡化图像

clipLimit颜色对比度的阈值
titleGridSize进行像素均衡化的网格大小,即在多少网格下进行直方图的均衡化操作

# 使用自适应直方图均衡化
# 第一步:实例化自适应直方图均衡化函数
img = cv2.imread('clahe.jpg',0) #0表示灰度图
clahe = cv2.createCLAHE(clipLimit=2.0,
                        tileGridSize=(8, 8))

# 第二步:进行自适应直方图均衡化
clahe = clahe.apply(img)

# 第三步:进行图像的展示
cv2.imshow('imgs', np.hstack((img, clahe)))
cv2.waitKey(0)
cv2.destroyAllWindows()

4. 金字塔(上采样、下采样)

高斯金字塔和拉普拉斯金字塔在这里插入图片描述
下采样:cv2.pyrDown(src, dstsize=[nrow, ncol])
上采样:cv2.pyrUp(src,dstsize=[ncol, nrow])
要注意的是上采样中的dstsize中的尺寸顺序与常规顺序是反着的,顺序为 高,宽

import os
import cv2
import matplotlib.pyplot as plt
import numpy as np
import time


def pyrGuassian(image):
    # 高斯金字塔
    level = 3
    downImages = []
    temp = image.copy()
    downImages.append(image)
    for i in range(level):
        img = cv2.pyrDown(temp)
        downImages.append(img)
        temp = img.copy()
        # cv2.imshow("pyr"+str(i), img)
    return downImages

def pyrLplance(imageList):
    level = len(imageList)
    for i in range(level-1, 0, -1):
        image = imageList[i]
        h, w = imageList[i-1].shape[:2]
        # v2.pyrUp的参数dstsize和ndarray.shape(取前两位)是反序的,即 不能直接 dstsize=imageList[i-1].shape[:2]
        Ru = cv2.pyrUp(image, dstsize=[w, h])
        imageExp = cv2.subtract(imageList[i-1], Ru)
        cv2.imshow("imageExp_"+str(i), imageExp)


filePath1 = r'G:\NNdataSet\coco128\images\train2017\000000000030.jpg'

src = cv2.imread(filePath1)
pyrLplance(pyrGuassian(src))
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值