opencv4学习总结-图像绘制与填充

画线

API原型:
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
 int thickness = 1, int lineType = LINE_8, int shift = 0);

参数解释:

  • img:要绘图的画布
  • pt1:初始点
  • pt2:目标点
  • color:线条颜色
  • thickness:线条宽度
  • lineType:线形
  • shift:图像偏移(可以相对的移动位置和放缩自己大小)

示例:

using namespace cv;
using namespace std;


int main()
{
    Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);

    line(canvas, Point(10, 10), Point(300, 300), Scalar(0, 0, 255), 1, 8);
    imshow("canvas", canvas);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

画圆

API原型:
void circle(InputOutputArray img, Point center, int radius, 
const Scalar& color, int thickness = 1, 
int lineType = LINE_8, int shift = 0);

参数解释:

  • img:要绘图的画布
  • center:圆心位置
  • radius:半径
  • color:颜色
  • thickness:线条厚度,如果小于0也就是-1的话则填充圆形内部
  • lineType:线形
  • shift:偏移

示例:


using namespace cv;
using namespace std;


int main()
{
    Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);

    circle(canvas, Point(256, 256), 128, Scalar(0, 0, 255), -1, 8);
    imshow("canvas", canvas);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

画矩形

API原型:
void rectangle(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0);
void rectangle(InputOutputArray img, Rect rec,
 const Scalar& color, int thickness = 1,
 int lineType = LINE_8, int shift = 0);

原型1参数解释:

  • img:要绘图的画布
  • pt1:矩形左上角的点
  • pt2:矩形右下角的点
  • color:颜色
  • thickness:线宽
  • lineType:线形
  • shift:偏移

原型2参数解释:

  • img:要绘图的画布
  • rec:一个矩形对象,用左上的点坐标和长宽来定义
  • color:颜色
  • thickness:线宽
  • lineType:线形
  • shift:偏移

示例:


using namespace cv;
using namespace std;


int main()
{
    Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);

    rectangle(canvas, Point(156, 156), Point(356, 356), Scalar(0, 0, 255), 1, 8);
    rectangle(canvas, Rect(0, 0, 100, 100), Scalar(0, 255, 0), 1, 8);
    imshow("canvas", canvas);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

画椭圆

API原型:
void ellipse(InputOutputArray img, Point center, Size axes,
                        double angle, double startAngle, double endAngle,
                        const Scalar& color, int thickness = 1,
                        int lineType = LINE_8, int shift = 0);
void ellipse(InputOutputArray img, const RotatedRect& box, const Scalar& color,
                        int thickness = 1, int lineType = LINE_8);

原型1参数解释:

  • img:要绘图的画布
  • center:椭圆中心点
  • axes:椭圆的长轴短轴构成的矩形
  • angle:椭圆旋转的角度
  • startAngle:开始角度
  • endAngle:结束角度(开始角度和结束角度决定了是画一个完整的椭圆还是一段椭圆线
  • color:颜色
  • thickness:线宽
  • lineType:线形
  • shift:偏移

原型2参数解释

  • img:要绘图的画布
  • box:一个椭圆对象
  • 其余参数与原型1相同

示例:

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

using namespace cv;
using namespace std;


int main()
{
    Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);

    ellipse(canvas, Point(256, 256), Size(100, 50), 30, 0, 90, Scalar(0, 0, 255), 1, 8);
    RotatedRect rrt(Point(256, 256), Size(100, 50), 90);
    ellipse(canvas, rrt, Scalar(0, 255, 0), 1, 8);
    imshow("canvas", canvas);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

opencv4学习总结-图像像素信息统计

像素最大值最小值

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv/sources/samples/data/chicky_512.png",IMREAD_GRAYSCALE);
    imshow("src", src);
    int h = src.rows;
    int w = src.cols;
    int channels = src.channels();

    double min_val, max_val;
    Point minLoc;
    Point maxLoc;
    minMaxLoc(src, &min_val, &max_val, &minLoc, &maxLoc);//针对单通道Mat对象
    printf("minVal:%.2f,loc:(%d,%d)\nmaxVal:%.2f,loc:(%d,%d)\n", min_val, minLoc.x, minLoc.y, max_val, maxLoc.x, maxLoc.y);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

均值和方差

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv/sources/samples/data/chicky_512.png");
    imshow("src", src);
    int h = src.rows;
    int w = src.cols;
    int channels = src.channels();

    Scalar s = mean(src);//计算每个通道的平均像素值
    printf("mean channel B:%.2f,mean channel G:%.2f,mean channel R:%.2f\n", s[0], s[1], s[2]);


    waitKey(0);
    destroyAllWindows();

    return 0;
}
using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv/sources/samples/data/chicky_512.png");
    imshow("src", src);
    int h = src.rows;
    int w = src.cols;
    int channels = src.channels();

    Mat mm, mstd;
    meanStdDev(src, mm, mstd);
    printf("mean:%.2f,%.2f,%.2f\n", mm.at<double>(0, 0), mm.at<double>(1, 0), mm.at<double>(2, 0));
    printf("std:%.2f,%.2f,%.2f\n", mstd.at<double>(0, 0), mstd.at<double>(1, 0), mstd.at<double>(2, 0));



    waitKey(0);
    destroyAllWindows();

    return 0;
}

opencv4学习总结-图像运算

图像加减乘除

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

using namespace cv;
using namespace std;


int main()
{
    Mat src1 = imread("E:/opencv_source/opencv/sources/samples/data/WindowsLogo.jpg");
    Mat src2 = imread("E:/opencv_source/opencv/sources/samples/data/LinuxLogo.jpg");
    imshow("src1", src1);
    imshow("src2", src2);
    //加法
    Mat dst1;
    add(src1, src2, dst1);
    imshow("add", dst1);
    //减法
    Mat dst2;
    subtract(src1, src2, dst2);
    imshow("subtract", dst2);
    //乘法
    Mat dst3;
    multiply(src1, src2, dst3);
    imshow("multiply", dst3);
    //除法
    Mat dst4;
    divide(src1, src2, dst4);
    imshow("divide", dst4);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

改变图像亮度

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv/sources/samples/data/chicky_512.png");
    imshow("src", src);
    //改变图像亮度
    Mat black = Mat::zeros(src.size(), src.type());
    black = Scalar(50, 50, 50);
    Mat dst;
    add(src, black, dst);
    imshow("dst1", dst);

    addWeighted(src, 1, black, 1, 20, dst);
    imshow("dst2", dst);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

图像位操作

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv/sources/samples/data/chicky_512.png");
    imshow("src", src);
    //设置mask
    Mat mask = Mat::zeros(src.size(), CV_8UC1);
    int h = src.rows / 2;
    int w = src.cols / 2;
    for (int row = 0; row < h; row++)
    {
        for (int col = 0; col < w; col++)
        {
            mask.at<uchar>(row, col) = 255;
        }
    }
    //取反
    Mat dst1;
    bitwise_not(src, dst1, mask);
    imshow("not", dst1);

    //与
    Mat dst2;
    bitwise_and(src, src,dst2, mask);
    imshow("and", dst2);

    //或
    Mat dst3;
    bitwise_or(src, src,dst3, mask);
    imshow("or", dst3);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

opencv4学习总结-Mat创建和使用

Mat类的介绍

Mat类表示n维单通道或多通道的密集数值数组,它可用于存储实值或复数向量和矩阵、灰度或彩色图像、体素体积、向量场、点云、张量、直方图。

使用实例

创建一个7×7的复数矩阵并用1+3j填充

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

using namespace cv;
using namespace std;


int main()
{
    Mat M(7, 7, CV_32FC2, Scalar(1, 3));



    waitKey(0);
    destroyAllWindows();

    return 0;
}

接下来打断点调试,更为生动的查看这段数据

下面这段内存就是存在矩阵M里面的数据,由于是32位矩阵,所以每段数据占四个字节,里面的0000803f从内存中提取出来就是0x3f800000,根据浮点数的转换规则,转换为十进制就是1.0,后面的0x40400000转换为浮点数十进制为3.0,可以观察到双通道的数据布局方式。

将上面矩阵转换为另一格式

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

using namespace cv;
using namespace std;


int main()
{
    Mat M(7, 7, CV_32FC2, Scalar(1, 3));
    M.create(100, 60, CV_8UC(15));


    waitKey(0);
    destroyAllWindows();

    return 0;
}

create函数会让让新的数据格式覆盖掉原先的数据

对Mat矩阵进行行列变换

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

using namespace cv;
using namespace std;


int main()
{
    Mat M(7, 7, CV_8UC1, Scalar(1));
    //第五行乘3加第三行赋值给第三行
    M.row(3) = M.row(3) + M.row(5) * 3;
    //把第六列复制给第一列,这里不能用等于号赋值,具体原因我还没搞明白,感觉可能是行和列格式不一样吧
    Mat M1 = M.col(1);
    M.col(6).copyTo(M1);

    waitKey(0);
    destroyAllWindows();

    return 0;
}

创建一个BGR3通道图像

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

using namespace cv;
using namespace std;


int main()
{
    //创建一个320×240的3通道BGR彩色图像
    Mat img(Size(320, 240), CV_8UC3);
    imshow("src", img);
    //定义一个img上的区域
    Mat roi(img, Rect(10, 10, 100, 100));
    //赋值为绿色
    roi = Scalar(0, 255, 0);
    imshow("dst", roi);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

对图像的复制,获取图像信息等操作

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

using namespace cv;
using namespace std;


int main()
{
	Mat image = imread("E:/opencv_source/opencv_tutorial_data-master/images/dog.jpg");
	Mat m1, m2;
	m1 = image.clone();
	image.copyTo(m2);

	//创建空白图像
	Mat m3 = Mat::zeros(Size(8, 8), CV_8UC1);
	std::cout << m3 << std::endl;
	//获取图像宽度
	int width = image.cols;
	//获取图像高度
	int height = image.rows;
	//获取图像通道数
	int dim = image.channels();
	int d = image.depth();
	int t = image.type();
	printf("width:%d,height:%d,channel:%d,depth:%d,type:%d\n", width, height, dim, d, t);

	//创建单通道8位矩阵
	Mat t1 = Mat(256, 256, CV_8UC1);
	//给t1赋值
	t1 = Scalar(0);
	imshow("t1", t1);
	Mat t2 = Mat(Size(256, 256), CV_8UC3);
	t2 = Scalar(255, 0, 255);
	imshow("t2", t2);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

对Mat进行遍历

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

using namespace cv;
using namespace std;


int main()
{
    Mat image = imread("E:/opencv_source/opencv_tutorial_data-master/images/dog.jpg",IMREAD_GRAYSCALE);
    if (image.empty())
    {
        printf("no such picture");
        return -1;
    }
    imshow("input", image);
    int height = image.rows;
    int width = image.cols;
    int channels = image.channels();
    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < width; col++)
        {
            if (channels == 3)
            {
                Vec3b pixel = image.at<Vec3b>(row, col);
                int blue = pixel[0];
                int green = pixel[1];
                int red = pixel[2];
                image.at<Vec3b>(row, col)[0] = 255 - blue;
                image.at<Vec3b>(row, col)[1] = 255 - green;
                image.at<Vec3b>(row, col)[2] = 255 - red;
            }
            else if (channels == 1)
            {
                int p = image.at<uchar>(row, col);
                image.at<uchar>(row, col) = 255 - p;
            }
        }
    }
    imshow("output", image);


    waitKey(0);
    destroyAllWindows();

    return 0;
}