文章目录
相关链接
前言
今天来接着学习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++的环境配置实在是过于麻烦,要修改项目配置,还要修改文件内容,还要添加环境变量。我这里就不做对应的配置了。我尝试配置了一下,没配置出来
#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反而是最简单的了。
错误代码
 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:\Anaconda3\python311.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遍历
我这里就直接上结果了
/// <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:\Anaconda3\python311.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++ 作为开发软件,只是单纯的稍微了解一下。










