opencv4学习总结-图像梯度

robot算子计算梯度

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/home.jpg");
    imshow("src", src);
    
    Mat robotx = (Mat_<int>(2, 2) << 1, 0, 0, -1);
    Mat roboty = (Mat_<int>(2, 2) << 0, 1, -1, 0);
    Mat grad_x, grad_y;
    filter2D(src, grad_x, CV_32F, robotx, Point(-1, -1), 0, BORDER_DEFAULT);
    filter2D(src, grad_y, CV_32F, roboty, Point(-1, -1), 0, BORDER_DEFAULT);
    convertScaleAbs(grad_x, grad_x);
    convertScaleAbs(grad_y, grad_y);
    Mat result;
    add(grad_x, grad_y, result);
    imshow("grad_x", grad_x);
    imshow("grad_y", grad_y);
    imshow("result", result);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

sobel算子

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/home.jpg");
    imshow("src", src);
    
    Mat grad_x, grad_y;

    Sobel(src, grad_x, CV_32F, 1, 0);
    Sobel(src, grad_y, CV_32F, 0, 1);
    convertScaleAbs(grad_x, grad_x);
    convertScaleAbs(grad_y, grad_y);

    Mat result;
    add(grad_x, grad_y, result);
    imshow("grad_x", grad_x);
    imshow("grad_y", grad_y);
    imshow("result", result);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

scharr算子

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/home.jpg");
    imshow("src", src);
    
    Mat grad_x, grad_y;

    Scharr(src, grad_x, CV_32F, 1, 0);
    Scharr(src, grad_y, CV_32F, 0, 1);
    convertScaleAbs(grad_x, grad_x);
    convertScaleAbs(grad_y, grad_y);

    Mat result;
    add(grad_x, grad_y, result);
    imshow("grad_x", grad_x);
    imshow("grad_y", grad_y);
    imshow("result", result);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

opencv4学习总结-自定义滤波

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/home.jpg");
    imshow("src", src);
    //均值卷积
    int k = 15;
    Mat mkernel = Mat::ones(k, k, CV_32F) / (float)(k * k);
    Mat dst;
    filter2D(src, dst, -1, mkernel, Point(-1, -1), 0, BORDER_DEFAULT);
    imshow("mean filter", dst);

    //非均值滤波
    Mat robot = (Mat_<int>(2, 2) << 1, 0, 0, -1);

    Mat result;
    filter2D(src, result, -1, robot, Point(-1, -1), 0, BORDER_DEFAULT);
    imshow("robot filter", result);

    waitKey(0);
    destroyAllWindows();

    return 0;
}

opencv4学习总结-图像模糊

盒子模糊(normalize设置为true就相当于均值模糊,跟blur函数一样)

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/home.jpg");
    imshow("src", src);

    Mat dst;
    boxFilter(src, dst, -1, Size(10, 10), Point(-1, -1), true, BORDER_DEFAULT);
    imshow("dst", 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_tutorial_data-master/images/home.jpg");
    imshow("src", src);

    Mat dst;
    GaussianBlur(src, dst, Size(11, 11), 0);
    imshow("dst", dst);

    waitKey(0);
    destroyAllWindows();

    return 0;
}

opencv4学习总结-图像卷积

基础卷积操作

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/home.jpg");
    imshow("src", src);

	int h = src.rows;
	int w = src.cols;
	Mat result = src.clone();
	float filter[3][3] = { 1,1,1,
							1,1,1,
							1,1,1 };
	for (int row = 1; row < h - 1; row++)
	{
		for (int col = 1; col < w - 1; col++)
		{
			//3×3卷积
			int sb = src.at<Vec3b>(row - 1, col - 1)[0]*filter[0][0] + src.at<Vec3b>(row - 1, col)[0] * filter[0][1] + src.at<Vec3b>(row - 1, col + 1)[0] * filter[0][2] +
				src.at<Vec3b>(row, col - 1)[0] * filter[1][0] + src.at<Vec3b>(row, col)[0] * filter[1][1] + src.at<Vec3b>(row, col + 1)[0] * filter[1][2] +
				src.at<Vec3b>(row + 1, col - 1)[0] * filter[2][0] + src.at<Vec3b>(row + 1, col)[0] * filter[2][1] + src.at<Vec3b>(row + 1, col + 1)[0] * filter[2][2];

			int sg = src.at<Vec3b>(row - 1, col - 1)[1] * filter[0][0] + src.at<Vec3b>(row - 1, col)[1] * filter[0][1] + src.at<Vec3b>(row - 1, col + 1)[1] * filter[0][2] +
				src.at<Vec3b>(row, col - 1)[1] * filter[1][0] + src.at<Vec3b>(row, col)[1] * filter[1][1] + src.at<Vec3b>(row, col + 1)[1] * filter[1][2] +
				src.at<Vec3b>(row + 1, col - 1)[1] * filter[2][0] + src.at<Vec3b>(row + 1, col)[1] * filter[2][1] + src.at<Vec3b>(row + 1, col + 1)[1] * filter[2][2];

			int sr = src.at<Vec3b>(row - 1, col - 1)[2] * filter[0][0] + src.at<Vec3b>(row - 1, col)[2] * filter[0][1] + src.at<Vec3b>(row - 1, col + 1)[2] * filter[0][2] +
				src.at<Vec3b>(row, col - 1)[2] * filter[1][0] + src.at<Vec3b>(row, col)[2] * filter[1][1] + src.at<Vec3b>(row, col + 1)[2] * filter[1][2] +
				src.at<Vec3b>(row + 1, col - 1)[2] * filter[2][0] + src.at<Vec3b>(row + 1, col)[2] * filter[2][1] + src.at<Vec3b>(row + 1, col + 1)[2] * filter[2][2];
			result.at<Vec3b>(row, col)[0] = sb / 9;
			result.at<Vec3b>(row, col)[1] = sg / 9;
			result.at<Vec3b>(row, col)[2] = sr / 9;

		}
	}
	imshow("conv-demo", result);
	
    



    waitKey(0);
    destroyAllWindows();

    return 0;
}

卷积核都是1的情况:可以看到图变模糊了,也就是均值滤波

卷积核都是-1的情况:可以看到图跟取反效果是一样的

均值滤波

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/home.jpg");
    imshow("src", src);

    Mat dst;
    blur(src, dst, Size(10, 10), Point(-1, -1), BORDER_DEFAULT);
    imshow("dst", 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_tutorial_data-master/images/home.jpg");
    imshow("src", src);

    int border = 50;
    Mat border_m;
    copyMakeBorder(src, border_m, border, border, border, border, BORDER_DEFAULT);
    imshow("border", border_m);

    waitKey(0);
    destroyAllWindows();

    return 0;
}

opencv4学习总结-图像查找表

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/malware.png");
    imshow("src", src);

    Mat color = imread("E:/opencv_source/opencv_tutorial_data-master/images/lut.png");
    Mat lut = Mat::zeros(256, 1, CV_8UC3);
    for (int i = 0; i < 256; i++)
    {
        lut.at<Vec3b>(i, 0) = color.at<Vec3b>(10, i);
    }
    imshow("color", color);
    Mat dst;
    LUT(src, lut, dst);
    imshow("lut-demo", dst);

    //自带颜色查找表
    applyColorMap(src, dst, COLORMAP_AUTUMN);
    imshow("colormap-demo", dst);
    



    waitKey(0);
    destroyAllWindows();

    return 0;
}

opencv4学习总结-图像直方图统计

直方图计算

API:
void calcHist( const Mat* images, int nimages,
                          const int* channels, InputArray mask,
                          OutputArray hist, int dims, const int* histSize,
                          const float** ranges, bool uniform = true, bool accumulate = false );

参数说明:

  • images:输入的图片指针
  • nimages:计算的图片数量
  • channels:要计算图片哪个通道的直方图
  • mask:要计算的区域,直接Mat()就代表整张图片
  • hist:计算得到的直方图数组
  • dims:直方图通道的个数
  • histSize:把直方图分成多少个区间
  • ranges:统计像素的范围
  • uniform:是否归一化处理
  • accumulate:多个图像时是否对直方图进行累加计算
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/flower.png");
    imshow("src", src);
    vector<Mat> mv;
    split(src, mv);
    Mat b_hist,g_hist,r_hist;
    int histSize = 256;
    float range[] = {0,256};
    const float* ranges = { range };
    calcHist(&mv[0], 1, 0, Mat(), b_hist, 1, &histSize, &ranges, true, false);
    calcHist(&mv[1], 1, 0, Mat(), g_hist, 1, &histSize, &ranges, true, false);
    calcHist(&mv[2], 1, 0, Mat(), r_hist, 1, &histSize, &ranges, true, false);

    Mat result = Mat::zeros(Size(600, 400), CV_8UC3);
    int margin = 50;
    int nm = result.rows - 2 * margin;

    normalize(b_hist, b_hist, 0, nm, NORM_MINMAX, -1, Mat());
    normalize(g_hist, g_hist, 0, nm, NORM_MINMAX, -1, Mat());
    normalize(r_hist, r_hist, 0, nm, NORM_MINMAX, -1, Mat());

    float step = (result.cols - 2 * margin) / 256.0;
    for (int i = 0; i < 255; i++)
    {
        line(result, Point(step * i + 50, 50 + nm - b_hist.at<float>(i, 0)), Point(step * (i + 1) + 50, 50 + nm - b_hist.at<float>(i + 1, 0)), Scalar(255, 0, 0), 2, 8, 0);
        line(result, Point(step * i + 50, 50 + nm - g_hist.at<float>(i, 0)), Point(step * (i + 1) + 50, 50 + nm - g_hist.at<float>(i + 1, 0)), Scalar(0, 255, 0), 2, 8, 0);
        line(result, Point(step * i + 50, 50 + nm - r_hist.at<float>(i, 0)), Point(step * (i + 1) + 50, 50 + nm - r_hist.at<float>(i + 1, 0)), Scalar(0, 0, 255), 2, 8, 0);
    }
    line(result, Point(0, nm + 50), Point(result.cols, nm + 50), Scalar(255, 255, 255), 1, 8, 0);
    line(result, Point(50, result.rows), Point(50, 0), Scalar(255, 255, 255), 1, 8, 0);
    imshow("result", result);



    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_tutorial_data-master/images/flower.png");
    imshow("src", src);
    Mat dst, gray;
    
    cvtColor(src, gray, COLOR_BGR2GRAY);
    imshow("gray", gray);
    equalizeHist(gray, dst);
    imshow("dst", dst);



    waitKey(0);
    destroyAllWindows();

    return 0;
}

利用直方图计算图像相似度

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

using namespace cv;
using namespace std;


int main()
{
    Mat src1 = imread("E:/opencv_source/opencv_tutorial_data-master/images/malware.png");
    Mat src2 = imread("E:/opencv_source/opencv_tutorial_data-master/images/malware1.png");
    Mat src3 = imread("E:/opencv_source/opencv_tutorial_data-master/images/malware2.png");
    imshow("src1", src1);
    imshow("src2", src2);
    imshow("src3", src3);
    

    //直方图计算
    Mat hist1, hist2, hist3;
    int histSize[] = { 256,256,256 };
    int channels[] = { 0,1,2 };
    float c1[] = { 0,255 };
    float c2[] = { 0,255 };
    float c3[] = { 0,255 };
    const float* histRanges[] = { c1,c2,c3 };
    calcHist(&src1, 1, channels, Mat(), hist1, 3, histSize, histRanges, true, false);
    calcHist(&src2, 1, channels, Mat(), hist2, 3, histSize, histRanges, true, false);
    calcHist(&src3, 1, channels, Mat(), hist3, 3, histSize, histRanges, true, false);
    //归一化
    normalize(hist1, hist1, 0, 1.0, NORM_MINMAX, -1, Mat());
    normalize(hist2, hist2, 0, 1.0, NORM_MINMAX, -1, Mat());
    normalize(hist3, hist3, 0, 1.0, NORM_MINMAX, -1, Mat());

    //比较巴式距离
    double bh12 = compareHist(hist1, hist2, HISTCMP_BHATTACHARYYA);
    double bh13 = compareHist(hist1, hist3, HISTCMP_BHATTACHARYYA);
    double bh23 = compareHist(hist2, hist3, HISTCMP_BHATTACHARYYA);
    printf("bh12:%.2f,bh13:%.2f,bh23:%.2f\n", bh12, bh13, bh23);
    //相关性比较
    double ch12 = compareHist(hist1, hist2, HISTCMP_CORREL);
    double ch13 = compareHist(hist1, hist3, HISTCMP_CORREL);
    double ch23 = compareHist(hist2, hist3, HISTCMP_CORREL);
    printf("ch12:%.2f,ch13:%.2f,ch23:%.2f\n", ch12, ch12, ch23);
    



    waitKey(0);
    destroyAllWindows();

    return 0;
}

opencv4学习总结-图像通道合并与分离

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

using namespace cv;
using namespace std;


int main()
{
    Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/flower.png");
    imshow("src", src);
    vector<Mat> mv;
    //分离
    split(src, mv);
    int size = mv.size();
    printf("number of channels:%d\n", size);
    imshow("blue channel", mv[0]);
    imshow("green channel", mv[1]);
    imshow("red channel", mv[2]);

    //合并
    Mat dst;
    merge(mv, dst);
    imshow("merge", dst);


    waitKey(0);
    destroyAllWindows();

    return 0;
}

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;
}