发布时间:2023-03-17 12:00
下载完成后会得到一个 opencv-3.4.15-vc14_vc15.exe 文件,点击运行后会生成一个文件夹。
此文件夹为下一步工程创建使用,文件夹可移动、复制和重命名,这里命名如下:
附加包含目录:$(SolutionDir)\OpenCV3.4.15\opencv\build\include
附加lib库目录:$(SolutionDir)\OpenCV3.4.15\opencv\build\x64\vc15\lib
附加dll库目录:PATH=$(SolutionDir)\OpenCV3.4.15\opencv\build\x64\vc15\bin;%PATH%
Debug模式下的依赖项:opencv_world3415d.lib
Release模式下的依赖项:opencv_world3415.lib
至此配置完成,开启你的OpenCV之旅吧!
#include
#include
int main(int argc, char** argv)
{
std::cout << "OpenCV_Version: " << CV_VERSION << std::endl;
cv::waitKey(0);
return 0;
}
//示例一:以原格式读取并显示图像
#include
#include
using namespace cv;
int main(int argc, char** argv)
{
//读取图片
Mat img = imread("../images/liyifeng.jpg", cv::IMREAD_UNCHANGED);//以原图格式读取
if (img.empty()) {
std::cout << "加载图片失败" << std::endl;
}
else {
imshow("窗口1", img); //在窗口1中显示图片img(窗口大小不能调整)
imshow("窗口2", img); //在窗口2中显示图片img(窗口大小不能调整)
}
waitKey(0); //显示图片的窗口停顿
//waitKey(2000); //显示图片的窗口停顿2000ms
//destroyAllWindows(); //销毁所有的窗口
return 0;
}
//示例二:以灰度格式读取并显示图片
#include
#include
using namespace cv;
int main(int argc, char** argv)
{
Mat img = imread("../images/liyifeng.jpg", IMREAD_GRAYSCALE);//以灰度格式读取图片
if (img.empty()) {
std::cout << "加载图片失败" << std::endl;
}
else {
namedWindow("hello world", cv::WINDOW_FREERATIO); //创建一个名为hello world的窗口
imshow("hello world", img); //在hello world的窗口上显示图片img
}
waitKey(0); //显示图片的窗口停顿
//destroyAllWindows(); //销毁所有的窗口
return 0;
}
//WINDOW_FREERATIO:图片布满窗口,窗口大小也可以拉伸调整
#include
#include
using namespace cv;
int main(int argc, char** argv)
{
//读取图片
Mat img_source = imread("../images/liyifeng.jpg", IMREAD_UNCHANGED);//以原图格式读取
if (img_source.empty()) {
std::cout << "加载图片失败" << std::endl;
}
else {
Mat img_hsv, img_gray;
cvtColor(img_source, img_hsv, COLOR_BGR2HSV); //img_source转HSV格式,结果存到img_hsv中
cvtColor(img_source, img_gray, COLOR_BGR2GRAY); //img_source转灰度格式,结果存到img_gray中
imshow("img_hsv - HSV空间", img_hsv);
imshow("img_gray - 灰度空间", img_gray);
}
waitKey(0); //显示图片的窗口停顿
//destroyAllWindows(); //销毁所有的窗口
return 0;
}
//COLOR_BGR2GRAY = 6 : BGR到灰度
//COLOR_GRAY2BGR = 8 : 灰度到BGR
//COLOR_BGR2HSV = 40 : BGR到HSV
//COLOR_HSV2BGR = 54 : HSV到BGR
#include
#include
using namespace cv;
int main(int argc, char** argv)
{
//读取图片
Mat img_source = imread("../images/liyifeng.jpg", IMREAD_UNCHANGED);//以原图格式读取
if (img_source.empty()) {
std::cout << "加载图片失败" << std::endl;
}
else {
if (imwrite("../images/liyifeng_save.jpg", img_source)){ //注意.jpg是有损压缩,.png是无损压缩
std::cout << "图片保存成功" << std::endl;
}
else {
std::cout << "图片保存失败" << std::endl;
}
}
waitKey(0); //显示图片的窗口停顿
//destroyAllWindows(); //销毁所有的窗口
return 0;
}
// 示例一:创建
#include
#include
using namespace cv;
int main(int argc, char** argv)
{
Mat img = Mat::zeros(Size(4, 4), CV_8UC3); //CV_8UC3:8位、unsigned char、三通道
namedWindow("imgx 窗口", WINDOW_FREERATIO); //创建一个名为"imgx 窗口"的窗口
//显示一
std::cout << "显示一:显示图像的参数" << "\r\n";
std::cout << img << "\r\n"; //打印矩阵
std::cout << "dims:" << img.dims << "\r\n"; //打印维度
std::cout << "width:" << img.cols << "\r\n"; //打印宽度
std::cout << "height:" << img.rows << "\r\n"; //打印高度
std::cout << "size:" << img.size << "\r\n"; //打印尺寸
std::cout << "total:" << img.total() << "\r\n"; //打印像素总数
std::cout << "elemSize" << img.elemSize() << "\r\n"; //矩阵每个像素所占字节数(一个像素三个数组元素)
std::cout << "channel:" << img.channels() << "\r\n"; //矩阵每个像素所用通道数(一个像素三个数组元素)
std::cout << "type:" << cv::typeToString(img.type()) << "\r\n"; //矩阵每个像素的数据类型
std::cout << "depth:" << cv::depthToString(img.depth()) << "\r\n"; //矩阵每个像素的通道的数据类型
//显示二
std::cout << "显示二:图像的赋值操作" << "\r\n";
Mat imgx;
img.copyTo(imgx); //把img拷贝一份给imgx
imgx = Scalar(255, 0, 0); //imgx的每个像素点各通道都赋值成(0,0,255)
std::cout << imgx << "\r\n"; //打印矩阵
imshow("imgx 窗口", imgx);
//显示三(C++知识)
//Mat imgy = imgx; //浅拷贝
//imgx.copyTo(imgy); //条件深拷贝
//Mat imgy = imgx.clone(); //完全深拷贝
waitKey(0); //显示图片的窗口停顿
//destroyAllWindows(); //销毁所有的窗口
return 0;
}
//示例: 遍历与读写
#include
#include
using namespace cv;
int main(int argc, char** argv)
{
Mat image = Mat::zeros(Size(2, 2), CV_8UC3); //CV_8UC3:8位三通道
int width = image.cols; //列
int height = image.rows; //行
int channel = image.channels(); //通道数
//一、修改图像各点像素值
switch (channel) {
case 1: {
image.at(0, 0) = 0x00; image.at(0, 1) = 0xFF;
image.at(1, 0) = 0xFF; image.at(1, 1) = 0x00;
break;
}
case 3: { //彩色图像
image.at(0, 0) = { 0,0,255 }; image.at(0, 1) = { 0,255,0 }; // 00 01
image.at(1, 0) = { 255,0,0 }; image.at(1, 1) = { 0,0,0 }; // 10 11
//image.at(row, col)[0] = 0; //写、(单独写一个像素B通道)
//image.at(row, col)[1] = 255; //写、(单独写一个像素G通道)
//image.at(row, col)[2] = 0; //写、(单独写一个像素R通道)
break;
}
default: {break; }
}
//二、遍历图像读取像素值
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
switch (channel) {
case 1: {//灰度图像(row=行,col=列)
int pv = image.at(row, col); //读
std::cout << "row,col=" << pv << "\r\n";
break;
}
case 3: { //彩色图像
Vec3b bgr = image.at(row, col);//读
std::cout << "row,col=" << bgr << "\r\n";
break;
}
default: {break; }
}
}
}
cv::namedWindow("imgx 窗口", WINDOW_FREERATIO); //创建一个名为"imgx 窗口1"的窗口
cv::imshow("imgx 窗口", image);
cv::waitKey(0); //显示图片的窗口停顿
//cv::destroyAllWindows(); //销毁所有的窗口
return 0;
}
opencv3.4.1.15之后的版本,在某些识别算法上商业化了,所以建议使用3.4.1.15版本的,但是由于conda和pip中已经搜不到opencv3.4.1.15的版本了,这里提供pip的离线安装包下载:
文件下载地址:https://download.csdn.net/download/BaoTTing/85133357
离线安装命令:pip install folder:xxx.whl
(说明:资源已经限制在5积分下载,不会动态调整)
//示例、几何绘制
# 这是一个示例 Python 脚本。
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
img = np.zeros((512, 512, 3), np.uint8)
cv.line(img, (0, 0), (511, 511), (255, 0, 0), 5)
cv.circle(img, (256, 256), 60, (0, 0, 255), -1)
cv.rectangle(img, (100, 100), (400, 400), (0, 255, 0), 5)
cv.putText(img, "hello", (100, 150), cv.FONT_HERSHEY_COMPLEX, 5, (255, 255, 255), 3)
plt.imshow(img[:, :, ::-1])
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、像素修改和格式获取
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
img = cv.imread("ant.jpg", cv.IMREAD_UNCHANGED)
px = img[50, 50] # 获取某个像素点的值
print("px = ", px) # 打印px的值
blue = img[50, 50, 0] # 仅获取蓝色通道的强度值
print("blue = ", blue) # 打印blue的值
print("img.shape = ", img.shape) # 打印像素尺寸
print("img.size = ", img.size) # 打印有
print("img.dtype = ", img.dtype) # 打印通道的数据类型
img[100, 100] = [255, 255, 255] # 修改某个位置的像素值
img[100, 101] = [255, 255, 255] # 修改某个位置的像素值
img[100, 102] = [255, 255, 255] # 修改某个位置的像素值
img[100, 103] = [255, 255, 255] # 修改某个位置的像素值
img[100, 104] = [255, 255, 255] # 修改某个位置的像素值
plt.imshow(img[:, :, ::-1]) # BGR转RGB
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、边界填充
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 1、读取图像
img = cv.imread("ant.jpg", cv.IMREAD_UNCHANGED)
# 2、边界填充尺寸
top_size, bottom_size, left_size, right_size = (50, 50, 50, 50)
# 3、边界填充
replicate = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_REPLICATE) # 边缘复制
reflect1 = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_REFLECT) # 反射法1
reflect2 = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_REFLECT_101) # 反射法2
wrap = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_WRAP) # 外包装法
constant = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_CONSTANT, value=0) # 常量填充
# 5、使用matplot进行图像显示
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 8), dpi=100)
axes[0, 0].imshow(img[:, :, ::-1])
axes[0, 0].set_title("原图")
axes[0, 1].imshow(replicate[:, :, ::-1])
axes[0, 1].set_title("边缘复制")
axes[0, 2].imshow(reflect1[:, :, ::-1])
axes[0, 2].set_title("反射法1")
axes[1, 0].imshow(reflect2[:, :, ::-1])
axes[1, 0].set_title("反射法2")
axes[1, 1].imshow(wrap[:, :, ::-1])
axes[1, 1].set_title("外包装法")
axes[1, 2].imshow(constant[:, :, ::-1])
axes[1, 2].set_title("常量填充")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、图像的分割与合并
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
img = cv.imread("ant.jpg", cv.IMREAD_UNCHANGED)
b, g, r = cv.split(img) # 通道拆分
img = cv.merge((b, g, r)) # 通道合并
plt.subplot(1, 2, 1)
plt.imshow(b)
img = img[:, :, ::-1] # BGR转RGB
plt.subplot(1, 2, 2)
plt.imshow(img) # 对图像进行处理
plt.show() # 对图像进行显示
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、图像格式的转换、色彩空间
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
input_img = cv.imread("ant.jpg", cv.IMREAD_UNCHANGED)
img_hsv = cv.cvtColor(input_img, cv.COLOR_BGR2HSV)
img_gray = cv.cvtColor(input_img, cv.COLOR_BGR2GRAY)
plt.subplot(1, 2, 1)
plt.imshow(img_hsv)
plt.subplot(1, 2, 2)
plt.imshow(img_gray, cmap=plt.cm.gray)
plt.show() # 对图像进行显示
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、图像的加法
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 1、数值加法
# numpy的加法是饱和取模运算、超过边界取模值
# OpenCV的加法是饱和取边界操作、超过边界取边界值
x = np.uint8([250])
y = np.uint8([10])
print("numpy add=", x+y) # numpy-> 250 + 10 = 260%256 = 4
print("OpenCV add=", cv.add(x, y)) # OpenCV-> 250 + 10 = 255
# 对比两种加法,可见OpenCV的加法更常用(减法也是cv比较常用)
# 2、图像加法
img1 = cv.imread("view.jpg")
img2 = cv.imread("rain.jpg")
npadd_img = img1 + img2
cvadd_img = cv.add(img1, img2)
# 3、图像显示
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
axes[0].imshow(npadd_img[:, :, ::-1])
axes[0].set_title("np add")
axes[1].imshow(cvadd_img[:, :, ::-1])
axes[1].set_title("cv add")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、图像的混合
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 图像的混合也是加法,不同的是两幅图像的权重不同,给人一种混合或者透明的感觉。
# 即 g(x) = (1-a)*f0(x)+a*f1(x),改变a的值可以实现非常炫酷的混合。
# cv2.addWeight()可以按公式: dst = a*img1+b*img2+c进行混合(取c=0即可)。
img1 = cv.imread("view.jpg")
img2 = cv.imread("rain.jpg")
img_blend_1 = cv.addWeighted(img1, 0.7, img2, 0.3, 0)
img_blend_2 = cv.addWeighted(img1, 0.3, img2, 0.7, 0)
# 图像显示
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
axes[0].imshow(img_blend_1[:, :, ::-1])
axes[0].set_title("a=0.7,b=0.3,c=0")
axes[1].imshow(img_blend_2[:, :, ::-1])
axes[1].set_title("a=0.3,b=0.7,c=0")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、图像缩放
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 图像缩放:对图像的大小进行调整,即图像的放大或者缩小
# 函数:cv2.resize(src,desize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR)
# src:输入图像
# dsize:绝对尺寸,直接指定调整后图像大小
# fx,fy:相对尺寸,将desize设置为None,然后将fx,fy设置为比例因子即可
# interpolation:插值方法
# cv2.INTER_LINEAR:双线性插值法
# cv2.INTER_NEAREST:最近邻插值
# cv2.INTER_AREA:像素区域重采样
# cv2.INTER_CUBIC:双三次插值法
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
img_src = cv.imread("kids.jpg")
rows, cols = img_src.shape[:2]
print("img_src_size:", img_src.shape)
# 绝对尺寸
img_abs = cv.resize(img_src, (2 * cols, 2 * rows), interpolation=cv.INTER_CUBIC)
print("img_abs_size:", img_abs.shape)
# 相对尺寸
img_com = cv.resize(img_src, None, fx=0.5, fy=0.5)
print("img_com_size:", img_com.shape)
# 1、使用cv进行图像显示
cv.imshow("img_src", img_src)
cv.imshow("img_abs", img_abs)
cv.imshow("img_com", img_com)
cv.waitKey(0)
# 2、使用matplot进行图像显示
# fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
# axes[0].imshow(img_src[:, :, ::-1])
# axes[0].set_title("原始图片(放大)")
# axes[1].imshow(img_abs[:, :, ::-1])
# axes[1].set_title("绝对尺寸(放大)")
# axes[2].imshow(img_com[:, :, ::-1])
# axes[2].set_title("相对尺寸(缩小)")
# plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、图像平移
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 图像平移:将图像按照指定的方向和距离,移动相应的位置
# 函数:cv2.wrapAffine(img, M, dsize)
# img:输入图像
# M:2*3的移动矩阵,对于(x, y)处的像素点, 要把它移动到(x+tx,y+ty处),使用如下矩阵
# M = [ 1 0 tx]
# [ 0 1 ty]
# 注意:将M设置为np.float32类型的Numpy数组
# desize: 输出图像的大小,它是(width,height)的形式,即(列数,行数)
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
img_src = cv.imread("kids.jpg")
rows, cols = img_src.shape[:2]
print("img_src_size:", img_src.shape)
# 图像平移
M = np.float32([[1, 0, 100], [0, 1, 50]])
img_trans1 = cv.warpAffine(img_src, M, (cols, rows))
img_trans2 = cv.warpAffine(img_src, M, (2*cols, 2*rows))
print("img_trans1_size:", img_trans1.shape)
print("img_trans2_size:", img_trans1.shape)
# 1、使用cv进行图像显示
cv.imshow("img_src", img_src)
cv.imshow("img_trans1", img_trans1)
cv.imshow("img_trans2", img_trans2)
cv.waitKey(0)
# 2、使用matplot进行图像显示
# fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
# axes[0].imshow(img_src[:, :, ::-1])
# axes[0].set_title("原始图片")
# axes[1].imshow(img_trans1[:, :, ::-1])
# axes[1].set_title("平移图片1")
# axes[2].imshow(img_trans2[:, :, ::-1])
# axes[2].set_title("平移图片2")
# plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、图像旋转
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# API函数1:cv2.getRotationMatrix2D(center,angle,scale) 获取旋转矩阵
# center:旋转中心
# angle:旋转角度
# scale:缩放比例
# API函数2:cv2.wrapAffine() 用法见示例八
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
img_src = cv.imread("kids.jpg")
rows, cols = img_src.shape[:2]
print("img_src_size:", img_src.shape)
# 图像旋转
M = cv.getRotationMatrix2D((cols/2, rows/2), 45, 1.0) # 获取旋转矩阵
img_rotate = cv.warpAffine(img_src, M, (cols, rows))
print("img_rotate_size:", img_rotate.shape)
# 使用cv进行图像显示
cv.imshow("img_src", img_src)
cv.imshow("img_rotate", img_rotate)
cv.waitKey(0)
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、仿射变换
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 仿射变换涉及图像的形状位置角度的变化,是深度学习与预处理中常用到的功能,仿射变换主要是对图像的缩放、旋转、翻转、平移等操作的组合
# 在OpenCV中,仿射变换是一个2*3的矩阵 M=[A B] <其实就是建立一种映射关系A->B>
# API函数1:cv2.getAffineTransform(src, dst) 获取仿射变换矩阵
# src:原坐标
# dst:映射坐标
# API函数2:cv2.wrapAffine() 用法见示例八
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 1、图像读取
img_src = cv.imread("kids.jpg")
print("img_src_size:", img_src.shape)
# 2、仿射变换
rows, cols = img_src.shape[:2]
# 2.1、创建变换矩阵
pst1 = np.float32([[50, 50], [200, 50], [50, 200]])
pst2 = np.float32([[100, 100], [200, 50], [100, 250]])
M = cv.getAffineTransform(pst1, pst2)
# 2.2、进行图像的仿射变换
img_dst = cv.warpAffine(img_src, M, (cols, rows))
print("img_rotate_size:", img_dst.shape)
# 1、使用cv进行图像显示
cv.imshow("img_src", img_src)
cv.imshow("img_rotate", img_dst)
cv.waitKey(0)
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、透射变换
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 透射变换是视角变化的结果,是指利用透视中心、像点、目标点、三点共线的条件,按照透视变换定律使得透
# 视面(承影面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光束,仍能保持承影面上投影几何不变的变换。
# API函数1:cv2.getPerspectiveTransform(pts1, pts2)
# API函数2:cv2.wrapPerspective() 用法见示例八
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 1、图像读取
img_src = cv.imread("kids.jpg")
print("img_src_size:", img_src.shape)
# 2、投射变换
rows, cols = img_src.shape[:2]
# 2.1、创建变换矩阵
pst1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
pst2 = np.float32([[100, 145], [300, 100], [80, 290], [310, 300]])
M = cv.getPerspectiveTransform(pst1, pst2)
# 2.2、进行图像的仿射变换
img_dst = cv.warpPerspective(img_src, M, (cols, rows))
print("img_rotate_size:", img_dst.shape)
# 1、使用cv进行图像显示
cv.imshow("img_src", img_src)
cv.imshow("img_rotate", img_dst)
cv.waitKey(0)
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、图像金字塔
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 图像金字塔是图像多尺寸表达,类似OpenGL中的mip纹理,以多种分辨率来解释图像的有效表达
# 图像金字塔用于机器视觉和图像压缩,一幅图像金字塔是一系列以金字塔形状排列的分辨率逐渐降低
# 且来源于同一张原始图的图像集合,其通过梯次向下采样获得,直到达到某个终止条件才停止采样
# 金字塔的底部是待处理的图像高分辨率表示,而顶部是低分辨率的近似,图像越高,分辨率越低
# API函数1、cv.pyrUp(img) #对图像进行上采样,分辨率增大
# API函数2、cv.pyrDown(img) #对图像进行下采样,分辨率降低
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 1、图像读取
img_src = cv.imread("kids.jpg")
print("img_src_size:", img_src.shape)
# 2、图像金字塔
rows, cols = img_src.shape[:2]
# 2.1、图片上采样
img_Up = cv.pyrUp(img_src)
print("img_Up_size:", img_Up.shape)
# 2.2、图像下采样
img_Down = cv.pyrDown(img_src)
print("img_Down_size:", img_Down.shape)
# 1、使用cv进行图像显示
cv.imshow("img_Up", img_Up)
cv.imshow("img_src", img_src)
cv.imshow("img_Down", img_Down)
cv.waitKey(0)
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、腐蚀与膨胀
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 图像邻接:每个像素周围有8个邻接像素,常见的邻接关系有4邻接、8邻接、D邻接
# 图像的连通:1、两个像素是否相邻。2、两个像素的像素值是否满足特定的相似准则
# 4连通:对于具有值V的像素p和q,如果q在p的4邻接中,则称这两个像素为4连通
# 8连通:对于具有值V的像素p和q,如果q在p的8邻接中,则称这两个像素为8连通
# m连通:对于具有值V的像素p和q,如果q在p的4邻接或D邻接中,且p的4邻接和q的4邻接不相交(交集中没有值为V的像素),则称这两个像素为m连通
# 腐蚀:局部最小值,(消除物体的边界点,使目标缩小,可用于消除小于结构元素的噪声点)
# 膨胀:局部最大值,(将与物体接触的所有背景点合并到物体中,使目标增大,可填补目标中的孔洞)
# API函数1:cv2.erode(img, kernel, iterations)
# API函数2:cv2.dilate(img, kernel, iterations)
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 1、图像读取
img_src = cv.imread("letter.png")
print("img_src_size:", img_src.shape)
# 2、创建核结构
kernel = np.ones((5, 5), np.uint8)
# 3、图像腐蚀
img_erode = cv.erode(img_src, kernel)
# 4、图片膨胀
img_dilate = cv.dilate(img_src, kernel)
# 5、使用matplot进行图像显示
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
axes[0].imshow(img_src[:, :, ::-1])
axes[0].set_title("img_src")
axes[1].imshow(img_erode[:, :, ::-1])
axes[1].set_title("img_erode")
axes[2].imshow(img_dilate[:, :, ::-1])
axes[2].set_title("img_dilate")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、开、闭操作
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 开操作是先腐蚀后膨胀,作用是分离物体,消除小区域,消除噪点,去除小的干扰块。
# 闭操作是先膨胀后腐蚀,作用是消除闭合物体里面的孔洞,可以填充闭合区域
# API函数:cv2.morphologyEx(img, op, kernel)
# op=cv2.MORPH_OPEN:开操作
# op=cv2.MORPH_CLOSE:闭操作
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 1、图像读取
img_src1 = cv.imread("letteropen.png")
img_src2 = cv.imread("letterclose.png")
print("img_src1_size:", img_src1.shape)
print("img_src2_size:", img_src2.shape)
# 2、创建核结构
kernel = np.ones((10, 10), np.uint8)
# 3、图像开操作
img_src1_open = cv.morphologyEx(img_src1, cv.MORPH_OPEN, kernel)
# 4、图片闭操作
img_src2_close = cv.morphologyEx(img_src2, cv.MORPH_CLOSE, kernel)
# 5、使用matplot进行图像显示
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8), dpi=100)
axes[0, 0].imshow(img_src1[:, :, ::-1])
axes[0, 0].set_title("原图1")
axes[0, 1].imshow(img_src1_open[:, :, ::-1])
axes[0, 1].set_title("原图1开操作")
axes[1, 0].imshow(img_src2[:, :, ::-1])
axes[1, 0].set_title("原图2")
axes[1, 1].imshow(img_src2_close[:, :, ::-1])
axes[1, 1].set_title("原图2闭操作")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、礼帽与黑帽操作
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 礼帽操作:原图像与开运算的结果差(dst=src-open(src,element))
# 开运算的结果是放大了裂缝或局部低亮度区域,因此,从原图中减去开运算的图,得到的效果突出了比原图轮廓周围区域更明亮的区域,且这一操作和选择核的大小相关。
# 礼貌运算用来分离比临近点亮一些的斑块,当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取。
# 黑帽操作:闭运算与原图像的结果差(dst=close(src,element)-src)
# 黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。黑帽运算用来分离比邻近点暗一些的斑块。
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 1、读取图像
img_src1 = cv.imread("letteropen.png")
img_src2 = cv.imread("letterclose.png")
print("img_src1_size:", img_src1.shape)
print("img_src2_size:", img_src2.shape)
# 2、创建核结构
kernel = np.ones((10, 10), np.uint8)
# 3、图像开操作
img_src1_tophat = cv.morphologyEx(img_src1, cv.MORPH_TOPHAT, kernel)
# 4、图片闭操作
img_src2_blackhat = cv.morphologyEx(img_src2, cv.MORPH_BLACKHAT, kernel)
# 5、使用matplot进行图像显示
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8), dpi=100)
axes[0, 0].imshow(img_src1[:, :, ::-1])
axes[0, 0].set_title("原图1")
axes[0, 1].imshow(img_src1_tophat[:, :, ::-1])
axes[0, 1].set_title("原图1礼帽运算")
axes[1, 0].imshow(img_src2[:, :, ::-1])
axes[1, 0].set_title("原图2")
axes[1, 1].imshow(img_src2_blackhat[:, :, ::-1])
axes[1, 1].set_title("原图2黑帽操作")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、图像的平滑
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 均值滤波:
# API:cv2.blur(src, ksize, anchor, borderType)
# 高斯滤波:
# API:cv2.GaussianBlur(src,ksize,sigmaX,sigmay,borderType)
# 中值滤波:
# API:cv2.medianBlur(src, ksize)
# 双边滤波:
# API:cv.bilateralFilter(src, d, sigmaColor,sigmaSpace, dst, borderType)
if __name__ == '__main__':
# 1、读取图像
img_sp_src = cv.imread("dogsp.jpeg") # 带椒盐噪声原图
img_ga_src = cv.imread("dogGauss.jpeg") # 带高斯噪声原图
print("img_sp_size:", img_sp_src.shape)
print("img_ga_size:", img_ga_src.shape)
# 2、均值滤波
img_sp_dst1 = cv.blur(img_sp_src, (5, 5)) # 原图1的均值滤波
img_sp_dst2 = cv.blur(img_ga_src, (5, 5)) # 原图2的均值滤波
img_ga_dst = cv.GaussianBlur(img_ga_src, (3, 3), 1) # 高斯噪声(适合高斯噪声)
img_me_dst = cv.medianBlur(img_sp_src, 5) # 中值滤波(适合椒盐噪声)
# 5、使用matplot进行图像显示
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 8), dpi=100)
axes[0, 0].imshow(img_sp_src[:, :, ::-1])
axes[0, 0].set_title("带椒盐噪声原图1")
axes[0, 1].imshow(img_sp_dst1[:, :, ::-1])
axes[0, 1].set_title("原图1的均值滤波")
axes[0, 2].imshow(img_me_dst[:, :, ::-1])
axes[0, 2].set_title("原图1的中值滤波")
axes[1, 0].imshow(img_ga_src[:, :, ::-1])
axes[1, 0].set_title("带高斯噪声原图2")
axes[1, 1].imshow(img_sp_dst2[:, :, ::-1])
axes[1, 1].set_title("原图2均值滤波")
axes[1, 2].imshow(img_ga_dst[:, :, ::-1])
axes[1, 2].set_title("原图2高斯滤波")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、直方图均衡化
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 使用OpenCV中的方法统计直方图,并使用matplotlib将其绘制出来
# 掩膜的作用是提取感兴趣的区域(蒙版->掩膜)
# 直方图均衡化能提升对比度,用于处理曝光过度或曝光不足的图片
# 统计直方图的API:cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
if __name__ == '__main__':
# 1、读取图像
img_src = cv.imread("cat.jpeg", cv.IMREAD_GRAYSCALE) # 以灰度的格式读取图片
# 2、统计完整直方图(不带掩膜)
img_histr = cv.calcHist([img_src], [0], None, [256], [0, 256])
# 3、统计带掩膜的直方图
# 3.1、创建蒙版
mask = np.zeros(img_src.shape[:2], np.uint8)
mask[400:650, 200:500] = 1
# 3.2、创建掩膜
masked_img = cv.bitwise_and(img_src, img_src, mask=mask) # 蒙版与原图相与
# 3.3、原图带掩膜的直方图
mask_histr = cv.calcHist([img_src], [0], mask, [256], [0, 256])
# 4、对原图进行直方图均衡化
img_dst = cv.equalizeHist(img_src)
# 5、使用matplot进行图像显示
fig, axes = plt.subplots(nrows=3, ncols=2, figsize=(10, 6), dpi=100)
axes[0, 0].imshow(img_src, cmap=plt.cm.gray)
axes[0, 0].set_title("原图")
axes[0, 1].plot(img_histr)
axes[0, 1].set_title("原图直方图(不带掩膜)")
axes[0, 1].grid() # 添加网格
axes[1, 0].imshow(mask, cmap=plt.cm.gray)
axes[1, 0].set_title("蒙版数据")
axes[1, 1].imshow(masked_img, cmap=plt.cm.gray)
axes[1, 1].set_title("掩膜数据")
axes[2, 0].plot(mask_histr)
axes[2, 0].set_title("带掩膜的直方图")
axes[2, 0].grid() # 添加网格
axes[2, 1].imshow(img_dst, cmap=plt.cm.gray)
axes[2, 1].set_title("直方图均衡化结果")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、自适应均衡化
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 直方图均衡化是对图像整体的均衡,改变全局对比度,虽说能增强背景细节,但某些区域对比度好的区域在直方图均衡化后效果会变差
# cv.createCLAHE(clipLimit, tileGridSize)
# clipLimit: 对比度限制,默认是40
# tileGridSize: 分块的大小,默认为8*88∗8
if __name__ == '__main__':
# 1、读取图像
img_src = cv.imread("cat.jpeg", cv.IMREAD_GRAYSCALE) # 以灰度的格式读取图片
# 2、统计原图直方图
img_src_histr = cv.calcHist([img_src], [0], None, [256], [0, 256])
# 3、创建一个自适应均衡化的对象
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
# 4、自适应均衡化
img_dst = clahe.apply(img_src)
# 5、统计均衡化后的直方图
img_dst_histr = cv.calcHist([img_dst], [0], None, [256], [0, 256])
# 6、使用matplot进行图像显示
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 6), dpi=100)
axes[0, 0].imshow(img_src, cmap=plt.cm.gray)
axes[0, 0].set_title("原图")
axes[0, 1].plot(img_src_histr)
axes[0, 1].set_title("原图直方图")
axes[0, 1].grid() # 添加网格
axes[1, 0].imshow(img_dst, cmap=plt.cm.gray)
axes[1, 0].set_title("自适应均衡化")
axes[1, 1].plot(img_dst_histr)
axes[1, 1].set_title("均衡化后的直方图")
axes[1, 1].grid() # 添加网格
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、边缘检测之Sobel
# Sobel算子:用于边缘检测,简单效率高,虽然不如Canny检测准确,但实际很多场合,Sobel算子是首选(Sobel算子基于一阶导数)
# [ -1 +0 +1 ] [ -1 -2 -1 ]
# Gx = [ -2 +0 +2 ] Gy = [ +0 +0 +0 ] Gx用于检测水平变化,Gy用于检测垂直变化
# [ -1 +0 +1 ] [ +1 +2 +1 ]
# Scharr算子:当内核大小为3时,以上Sobel可能产生比较明显误差,我们使用Scharr算子替代来解决这个问题(Scharr仅适用于内核大小为3)
# [ -3 +0 +3 ] [ -3 -10 -3 ]
# Gx = [ -10 +0 +10 ] Gy = [ +0 +0 +0 ] Gx用于检测水平变化,Gy用于检测垂直变化
# [ -3 +0 +3 ] [ +3 +10 +3 ]
# API函数 cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
# (src:传入的图像)(ddepth:图像的深度)(dx和dy:指求导的阶数,0表示这个方向上没有求导,取值为0、1)
# (ksize:是Sobel算子的大小,即卷积核的大小,必须为奇数1、3、5、7,默认为3.注意:如果ksize=-1,就演变成为3x3的Scharr算子)
# (scale:缩放导数的比例常数,默认情况为没有伸缩系数)(borderType:图像边界的模式,默认值为cv2.BORDER_DEFAULT)
# ->Sobel函数求完导数后会有负值,还有会大于255的值。而原图像是uint8,即8位无符号数,所以Sobel建立的图像位数不够,会有截断。
# ->因此要使用16位有符号的数据类型,即cv2.CV_16S。处理完图像后,再使用cv2.convertScaleAbs()函数将其转回原来的uint8格式,否则图像无法显示。
# ->Sobel算子是在两个方向计算的,最后还需要用cv2.addWeighted()函数将其组合起来
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 主函数
if __name__ == '__main__':
# 1、读取图像
img_src = cv.imread("horse.jpg", cv.IMREAD_GRAYSCALE) # 以灰度的格式读取图片
# 2、计算Sobel卷积结果
sobel_x = cv.Sobel(img_src, cv.CV_16S, 1, 0) # Scharr: cv.Sobel(img_src, cv.CV_16S, 1, 0, ksize=-1)
sobel_y = cv.Sobel(img_src, cv.CV_16S, 0, 1) # Scharr: cv.Sobel(img_src, cv.CV_16S, 0, 1, ksize=-1)
# 3、将数据进行转换
scaleAbs_x = cv.convertScaleAbs(sobel_x)
scaleAbs_y = cv.convertScaleAbs(sobel_y)
# 4、结果合成
result = cv.addWeighted(scaleAbs_x, 0.5, scaleAbs_y, 0.5, 0)
# 5、使用matplot进行图像显示
plt.subplot(1, 2, 1), plt.imshow(img_src, cmap=plt.cm.gray), plt.title("原图")
plt.subplot(1, 2, 2), plt.imshow(result, cmap=plt.cm.gray), plt.title("Sobel滤波后结果")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、边缘检测之Laplacian(拉普拉斯)
# Laplacian算子:Laplacian是利用二阶导数来检测边缘
# [ +0 +1 +0 ]
# kernel = [ +1 -4 +1 ]
# [ +0 +1 +0 ]
# API函数:cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
# Src:需要处理的图像.
# Ddepth:图像的深度,-1表示采用的是原图像相同的深度,目标图像的深度必须大于等于原图像的深度.
# ksize:算子的大小,即卷积核的大小,必须为1,3,5,7.
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 主函数
if __name__ == '__main__':
# 1、读取图像
img_src = cv.imread("horse.jpg", cv.IMREAD_GRAYSCALE) # 以灰度的格式读取图片
# 2、laplacian
lap_dst = cv.Laplacian(img_src, cv.CV_16S)
img_dst = cv.convertScaleAbs(lap_dst)
# 3、使用matplot进行图像显示
plt.subplot(1, 2, 1), plt.imshow(img_src, cmap=plt.cm.gray), plt.title("原图")
plt.subplot(1, 2, 2), plt.imshow(img_dst, cmap=plt.cm.gray), plt.title("Laplacian滤波后结果")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
# 示例、边缘检测Canny
# Canny边缘检测算法是由4步构成,分别介绍如下:
# 第一步:噪声去除(由于边缘检测很容易受到噪声的影响,所以首先使用$5*5$高斯滤波器去除噪声)
# 第二步:计算图像梯度(对平滑后的图像使用Sobel算子计算水平方向和竖直方向的一阶导数(Gx和Gy),梯度方向分为四类:垂直,水平,和两个对角线方向)
# 第三步:非极大值抑制(在获得梯度的方向和大小之后,对整幅图像进行扫描,去除那些非边界上的点。对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的)
# 第四步:滞后阈值(现在要确定真正的边界。我们设置两个阈值:minVal和maxVal。当图像的灰度梯度高于maxVal时被认为是真的边界,
# 低于minVal的边界会被抛弃。如果介于两者之间的话,就要看这个点是否与某个被确定为真正的边界点相连,如果是就认为它也是边界点,如果不是就抛弃)
# API函数:cv2.Canny(image, threshold1, threshold2)
# image:灰度图。
# threshold1: minval,较小的阈值将间断的边缘连接起来。
# threshold2: maxval,较大的阈值检测图像中明显的边缘。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 主函数
if __name__ == '__main__':
# 1、读取图像
img_src = cv.imread("horse.jpg", cv.IMREAD_GRAYSCALE) # 以灰度的格式读取图片
# 2、Canny检测
img_dst = cv.Canny(img_src, 0, 100)
# 3、使用matplot进行图像显示
plt.subplot(1, 2, 1), plt.imshow(img_src, cmap=plt.cm.gray), plt.title("原图")
plt.subplot(1, 2, 2), plt.imshow(img_dst, cmap=plt.cm.gray), plt.title("Canny后的结果")
plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
常见算子的比较与总结:
所谓的模板匹配,就是在给定的图片中查找和模板最相似的区域,该算法的输入包括模板和图片,整个任务的思路就是按照滑窗的思路不断的移动模板图片,计算其与图像中对应区域的匹配度,最终将匹配度最高的区域选择为最终的结果。
实现流程:
准备两幅图像:
1.原图像(I):在这幅图中,找到与模板相匹配的区域
2.模板(T):与原图像进行比对的图像块