文章目录
- 相关链接
- 前言
- 测试图片
- 边界填充
-
- python
- C++
- Csharp
-
- 错误代码
- Mat遍历
- 最终代码和结果
- 总结
相关链接
C++&Python&Csharp in OpenCV 专栏
【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程(附带课程课件资料+课件笔记)
前言
今天来接着学习OpenCV,现在主要是以Python代码为主了,所以先实现Python,在用C++/Csharp重现一遍。
测试图片
边界填充
边界填充就是向外填充图片信息,将图片扩大。填充分为上下左右四个方向,所以我们要指定四个方向的填充大小。
python
# %% # 导入包 import cv2 import matplotlib.pyplot as plt import numpy as np image = cv2.imread("D:/workSpace/OpenCV/HellOpenCV/Resources/image/cat.png") # 声明填充区域 fill = { 'top':50, 'bottom':50, 'left':50, 'right':50 } # 填充也有很多的算法,我们这里尝试几个算法 replicate = cv2.copyMakeBorder(image,fill['top'],fill['bottom'],fill['left'],fill['right'], cv2.BORDER_REPLICATE) reflect = cv2.copyMakeBorder(image,fill['top'],fill['bottom'],fill['left'],fill['right'],cv2.BORDER_REFLECT) reflect101 = cv2.copyMakeBorder(image,fill['top'],fill['bottom'],fill['left'],fill['right'],cv2.BORDER_REFLECT_101) wrap = cv2.copyMakeBorder(image,fill['top'],fill['bottom'],fill['left'],fill['right'],cv2.BORDER_WRAP) constant = cv2.copyMakeBorder(image,fill['top'],fill['bottom'],fill['left'],fill['right'],cv2.BORDER_CONSTANT,value=0) plt.subplot(231),plt.imshow(image,'gray'),plt.title('ORIGINAL') plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('replicate') plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('reflect') plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('reflect101') plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('wrap') plt.subplot(236),plt.imshow(constant,'gray'),plt.title('constant') plt.show() # cv2.imshow("python",image) # cv2.waitKey(0) # cv2.destroyAllWindows()
C++
Python跑好了,但是C++和Csharp没有matplotlib.pyplot这个库,得去自己手动导入一下
额,我还是放弃了。我把相关的连接放在这里了,C++的环境配置实在是过于麻烦,要修改项目配置,还要修改文件内容,还要添加环境变量。我这里就不做对应的配置了。我尝试配置了一下,没配置出来
C++调用matplotlib绘图总结
c++调用matplotlib(一)
Visual Studio配置C++绘图库matplotlibcpp的方法
#include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc.hpp> #include<iostream> using namespace std; int main() { cv::Mat image = cv::imread("D:/workSpace/OpenCV/HellOpenCV/Resources/image/cat.png"); auto fill = new int[4] {50, 50, 50, 50}; //声明变量 cv::Mat replicate; cv::Mat reflect; cv::Mat reflect101; cv::Mat wrap; cv::Mat constant; //运行边界填充 cv::copyMakeBorder(image, replicate, fill[0], fill[1], fill[2], fill[3], cv::BORDER_REPLICATE); cv::copyMakeBorder(image, reflect, fill[0], fill[1], fill[2], fill[3], cv::BORDER_REFLECT); cv::copyMakeBorder(image, reflect101, fill[0], fill[1], fill[2], fill[3], cv::BORDER_REFLECT101); cv::copyMakeBorder(image, wrap, fill[0], fill[1], fill[2], fill[3], cv::BORDER_WRAP); cv::copyMakeBorder(image, constant, fill[0], fill[1], fill[2], fill[3], cv::BORDER_CONSTANT); cv::imshow("image", image); cv::imshow("replicate", replicate); cv::imshow("reflect", reflect); cv::imshow("reflect101", reflect101); cv::imshow("wrap", wrap); cv::imshow("constant", constant); cv::waitKey(0); cv::destroyAllWindows(); return 0; }
Csharp
Csharp我倒是跑通了,没想到Csharp反而是最简单的了。
PythonNet,Csharp如何白嫖Python生态和使用Matplotlib
错误代码
static void Main(string[] args) { Mat image = Cv2.ImRead("D:/workSpace/OpenCV/HellOpenCV/Resources/image/cat.png"); (int top, int bottom, int left, int right) fill = (50, 50, 50, 50); Mat replicate = new Mat(); Mat reflect = new Mat(); Mat reflect101 = new Mat(); Mat wrap = new Mat(); Mat constant = new Mat(); Cv2.CopyMakeBorder(image, replicate, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Replicate); Cv2.CopyMakeBorder(image, reflect, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Reflect); Cv2.CopyMakeBorder(image, reflect101, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Reflect101); Cv2.CopyMakeBorder(image, wrap, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Wrap); Cv2.CopyMakeBorder(image, constant, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Constant); //Cv2.ImShow("name",image); //Cv2.WaitKey(0); //选择你Python的dll位置 Runtime.PythonDLL = @"D:Anaconda3python311.dll"; //创建Python环境 PythonEngine.Initialize(); //展开Python的全局解释器 using (Py.GIL()) { dynamic plt = Py.Import("matplotlib.pyplot"); plt.subplot(231); plt.imshow(image, "gray"); plt.title("image"); plt.show(); Console.WriteLine("运行完毕"); Console.ReadLine(); } }
我们直接用是不可以的,因为他底层的代码不一样。matplotlib必须要是数组形式的数据输入。那我们需要将Mat转化为数组。
Mat遍历
Opencv:通过Mat遍历图像的5种方法
C++ 高效的遍历opencv Mat像素
我这里就直接上结果了
/// <summary> /// 3通道遍历 /// </summary> /// <param name="mat"></param> /// <returns></returns> public static int[,,] MatToArray(Mat mat) { var res = new int[mat.Rows, mat.Cols, mat.Channels()]; for(var i =0 ; i < mat.Rows;i++) { for(var j = 0 ; j < mat.Cols; j++) { var temp = mat.At<Vec3b>(i, j); res[i,j,0] = temp[0]; res[i,j,1] = temp[1]; res[i,j,2] = temp[2]; } } return res; }
最终代码和结果
internal class Program { static void Main(string[] args) { Mat image = Cv2.ImRead("D:/workSpace/OpenCV/HellOpenCV/Resources/image/cat.png"); (int top, int bottom, int left, int right) fill = (50, 50, 50, 50); Mat replicate = new Mat(); Mat reflect = new Mat(); Mat reflect101 = new Mat(); Mat wrap = new Mat(); Mat constant = new Mat(); Cv2.CopyMakeBorder(image, replicate, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Replicate); Cv2.CopyMakeBorder(image, reflect, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Reflect); Cv2.CopyMakeBorder(image, reflect101, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Reflect101); Cv2.CopyMakeBorder(image, wrap, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Wrap); Cv2.CopyMakeBorder(image, constant, fill.top, fill.bottom, fill.left, fill.right, BorderTypes.Constant); //选择你Python的dll位置 Runtime.PythonDLL = @"D:Anaconda3python311.dll"; //创建Python环境 PythonEngine.Initialize(); //展开Python的全局解释器 using (Py.GIL()) { dynamic plt = Py.Import("matplotlib.pyplot"); //转化成3通道数组 plt.subplot(231); plt.imshow(MatToArray(image), "gray"); plt.title("image"); plt.subplot(232); plt.imshow(MatToArray(replicate), "gray"); plt.title("replicate"); plt.subplot(233); plt.imshow(MatToArray(reflect), "gray"); plt.title("reflect"); plt.subplot(234); plt.imshow(MatToArray(reflect101), "gray"); plt.title("reflect101"); plt.subplot(235); plt.imshow(MatToArray(wrap), "gray"); plt.title("wrap"); plt.subplot(236); plt.imshow(MatToArray(constant), "gray"); plt.title("constant"); //展示结果 plt.show(); Console.WriteLine("运行完毕"); Console.ReadLine(); } } /// <summary> /// 3通道遍历 /// </summary> /// <param name="mat"></param> /// <returns></returns> public static int[,,] MatToArray(Mat mat) { var res = new int[mat.Rows, mat.Cols, mat.Channels()]; for(var i =0 ; i < mat.Rows;i++) { for(var j = 0 ; j < mat.Cols; j++) { var temp = mat.At<Vec3b>(i, j); res[i,j,0] = temp[0]; res[i,j,1] = temp[1]; res[i,j,2] = temp[2]; } } return res; } }
总结
今天不仅了解了一下这个代码,还顺便了解了一下Csharp怎么代用Python的matplotlib。C++ 没配成功,看网上的代码太麻烦了,而且我也不用C++ 作为开发软件,只是单纯的稍微了解一下。