图像的基本操作

2.图像基本操作

目录

2.图像基本操作

2.1图像的颜色空间

2.2图像像素处理

2.3图像变换

2.4绘制图像

2.5感兴趣的区域拷贝

2.6图像金字塔

2.7窗口交互操作


2.1图像的颜色空间

2.1.1颜色模型的互相转换

注意两个函数的使用;

cvtColor:表示的是不同颜色模型间的转换

convertTo:图像的数据类型转换函数

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    Mat img = imread("D:/classical.jpg");
    if (img.empty())
    {
        cout << "图片打卡失败,请重新选择文件路径" << endl;
        return -1;
    }
    Mat gray, HSV, YUV, Lab,img32;
    img.convertTo(img32, CV_32F, 1.0 / 255);
    cvtColor(img32,HSV,COLOR_BGR2HSV);
    cvtColor(img32, YUV, COLOR_BGR2YUV);
    cvtColor(img32,Lab,COLOR_BGR2Lab);
    cvtColor(img32,gray,COLOR_BGR2GRAY);
    imshow("原图",img32);
    imshow("HSV",HSV);
    imshow("YUV",YUV);
    imshow("Lab",Lab);
    imshow("gray",gray);
    waitKey(0);
    return 0;
}
​

2.1.2多通道分离与合并

split()函数--多通道分离 merge()函数--合并

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    //split()函数--多通道分离
    //merge()函数--合并
    Mat img = imread("D:/city.jpg");
    if (img.empty())
    {
        cout << "打开失败,重新选择图片路径" << endl;
        return -1;
    }
    Mat HSV;
    cvtColor(img, HSV, COLOR_RGB2HSV);
    Mat imgs0, imgs1, imgs2;//存放数组类型
    Mat imgv0, imgv1, imgv2;
    Mat result0, result1, result2;//存放合并的结果
    Mat imgs[3];
    split(img, imgs);
    imgs0 = imgs[0];
    imgs1 = imgs[1];
    imgs2 = imgs[2];
​
    imshow("RGB-B", imgs0);
    imshow("RGB-G", imgs1);
    imshow("RGB-R", imgs2);
    imgs[2] = img;
    merge(imgs, 3, result0);//合并图像
    //imshow("result0",result0);
    Mat zero;
    zero = Mat::zeros(img.rows, img.cols, CV_8UC1);
    imgs[0] = zero;
    imgs[2] = zero;
    merge(imgs, 3, result1);
    imshow("result1", result1);
​
​
    vector<Mat>imgv;
    split(HSV, imgv);
    imgv0 = imgv.at(0);
    imgv1 = imgv.at(1);
    imgv2 = imgv.at(2);
    imshow("HSV-H", imgv0);
    imshow("HSV-S",imgv1);
    imshow("HSV-V", imgv2);
    imgv.push_back(HSV);
    merge(imgv, result2);
    //imshow("result2", result2);
​
    waitKey(0);
    return 0;
​
}
​

2.2图像像素处理

2.2.1像素最大值和最小值

minMaxLoc函数

注意:多通道需要转换成单通道

需要用到reshape函数来对它进行转换成单通道

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    system("color F0");
    float a[12] = { 1,2,3,4,5,10,6,7,8,10,0 };
    Mat img = Mat(3,4,CV_32FC1,a);//单通道矩阵
    Mat imgs = Mat(2, 3, CV_32FC2,a);//多通道矩阵
    double minVal, maxVal;
    Point minIdx, maxIdx;
    minMaxLoc(img, &minVal, &maxVal, &minIdx, &maxIdx);
    cout << "img的最大值" <<maxVal<<"最大值的位置:"<<maxIdx<< endl;
    cout << "img的最小值" << minVal << "最小值的位置:" << minIdx << endl;
​
    //寻找多通道矩阵中的最值
    Mat imgs_re = imgs.reshape(1, 4);
    minMaxLoc(imgs_re, &minVal, &maxVal, &minIdx, &maxIdx);
    cout << "img的最大值" << maxVal << "最大值的位置:" << maxIdx << endl;
    cout << "img的最小值" << minVal << "最小值的位置:" << minIdx << endl;
    return 0;
​
}
​

图像的平均值和标准差

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    system("color F0");
    float a[12] = { 1,2,3,4,5,10,6,7,8,9,10,0 };
    Mat img = Mat(3,4,CV_32FC1,a);//单通道矩阵
    Mat imgs = Mat(2, 3, CV_32FC2,a);//多通道矩阵
    cout << "/*用mean的方式求去图像的平均值*/" << endl;
    Scalar mymean;
    mymean = mean(imgs);
    cout << "imgs平均值:"<<mymean << endl;
    cout << "第一个通道的平均值" <<mymean[0]<< "   "
        << "第二个通道的平均值为" << mymean[1] << endl<<endl;
​
    cout << "/*用meanstddev同时求取图像的平局值和标准差*/" << endl;
​
    Mat myMeanMat ,myStddevMat;
​
    meanStdDev(img, myMeanMat, myStddevMat);
    cout << "img的平均值" << myMeanMat<<endl;
    cout << "img的标准差" << myStddevMat << endl << endl;
​
    meanStdDev(imgs, myMeanMat, myStddevMat);
    cout << "imgs的平均值" << myMeanMat << endl;
    cout << "imgs的标准差" << myStddevMat << endl;
    return 0;
​
}
​

2.2.2两图像间的像素操作

max和min函数的比较

    system("color F0");
    float a[12] = { 1,2,3.3,4,5,9,5,7,8.2,9,10,2};
    float b[12] = { 1,2.2,3,1,3,10,6,7,8,9.3,10,1 };
​
    Mat imga = Mat(3,4,CV_32FC1,a);//单通道矩阵
    Mat imgb = Mat(3, 4, CV_32FC1, b);//单通道矩阵
​
    Mat imgc = Mat(2, 3, CV_32FC2,a);//多通道矩阵
    Mat imgd = Mat(2, 3, CV_32FC2, b);//多通道矩阵
​
​
    //对两个单通道矩阵进行比较运算
    Mat myMax, myMin;
    max(imga,imgb,myMax);
    min(imga, imgb, myMin);
​
    //对两个多通道矩阵进行比较运算
    Mat myMaxs, myMins;
    max(imgc, imgd, myMaxs);
    min(imgc, imgd, myMins);
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
​
    Mat img0 = imread("D:/city.jpg");
    Mat img1 = imread("D:/city.jpg");
    Mat HSV;
    cvtColor(img1, HSV, COLOR_RGB2HSV);
    if (img0.empty()||img1.empty())
    {
        cout << "请输入正确的文件名称" << endl;
        return -1;
    }
​
    Mat comMin, comMax;
    max(img0, HSV,comMax);
    min(img0,HSV,comMin);
    imshow("comMax",comMax);
    imshow("comMin",comMin);
​
    //与掩膜进行比较
    Mat src1 = Mat::zeros(Size(512, 512),CV_8UC3);
    Rect rect(100, 100, 300, 300);//矩形类
    src1(rect) = Scalar(255, 255, 255);//设 m 置颜色的。
    Mat comsrc1, comsrc2;
    min(img0, src1, comsrc1);
    imshow("comscr1",comsrc1);
​
    Mat src2=Mat (512, 512,CV_8UC3,Scalar(0,0,255));//设置颜色的。
    min(img0, src2, comsrc2);
    imshow("comscr2",comsrc2);
​
    //两幅灰度图进行比较
    Mat img0G, img1G, comMinG, comMaxG;
    cvtColor(img0, img0G, COLOR_BGR2GRAY);//转换成灰度图
    cvtColor(HSV, img1G, COLOR_BayerRG2GRAY);
    max(img0G, img1G, comMaxG);
    min(img0G, img1G, comMinG);
    imshow("comMaxG", comMaxG);
    imshow("comMinG", comMinG);
    waitKey(0); 
​
         
    return 0;
​
}
​

两幅图像的逻辑运算

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    Mat img = imread("D:/classical.jpg");
    if (img.empty())
    {
        cout << "打开文件失败" << endl;
        return -1;
    }
    Mat img0 = Mat::zeros(200, 200, CV_8UC1);
    Mat img1 = Mat::zeros(200, 200, CV_8UC1);
    Rect rect0 (50, 50, 100, 100);
    Rect rect1(100, 100, 100, 100);
    img0(rect0) = Scalar(255);
    img1(rect1) = Scalar(255);
    imshow("img0", img0);
    imshow("img1", img1);
    //进行逻辑运算
    Mat myAnd, myOr, myNot,myXor, imgNot;
    bitwise_and(img0, img1, myAnd);
    bitwise_not(img0, myNot);
    bitwise_or(img0, img1,myOr);
    bitwise_xor(img0, img1, myXor);
    bitwise_not(img,imgNot);
​
    imshow("myAnd", myAnd);
    imshow("myNot", myNot);
    imshow("myor", myOr);
    imshow("myxor", myXor);
    imshow("imgnot", imgNot);
    waitKey(0);  
    return 0;
​
}
​

2.2.3图像二值化

概念;将非二值化图像经过计算变成二值图像

二值图像:非黑即白,图像像素的灰度值无论在什么数据类型中只有最大值和最小值两种取值。

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    Mat img = imread("D:/classical.jpg");
    if (img.empty())
    {
        cout << "打开文件失败" << endl;
        return -1;
    }
    Mat gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);
    Mat img_B, img_B_V, gray_B, gray_B_V, gray_T, gray_T_V, gray_TRUNC;
​
​
    //彩色图像的二值化
    threshold(img, img_B, 125, 255, THRESH_BINARY);
    threshold(img, img_B_V, 125, 255, THRESH_BINARY_INV);
    imshow("img_B", img_B);
    imshow("img_b_v", img_B_V);
​
    //灰度图binary二值化
    threshold(gray, gray_B, 125, 255, THRESH_BINARY);
    threshold(gray, gray_B_V, 125, 255, THRESH_BINARY_INV);
    imshow("gray_b",gray_B);
    imshow("gray_b_v",gray_B_V);
​
​
    //灰度图像的tozero变换
    threshold(gray, gray_T, 125, 255, THRESH_BINARY);
    threshold(gray, gray_T_V, 125, 255, THRESH_BINARY_INV);
    imshow("gray_T", gray_T);
    imshow("gray_T_v", gray_T_V);
​
    //灰度图像trunc变换
    threshold(gray, gray_TRUNC, 125, 255, THRESH_TOZERO);      
    imshow("gray_trunc", gray_TRUNC);
​
    //灰度图像大律法和三角法二值化
    Mat img_thr = imread("D:/classical.jpg",IMREAD_GRAYSCALE);
    Mat img_thr_o, img_thr_t;
    threshold(img_thr, img_thr_o, 100, 255, THRESH_BINARY | THRESH_OTSU);
    threshold(img_thr, img_thr_t, 100, 255, THRESH_BINARY | THRESH_TRIANGLE);
    imshow("img_thr", img_thr);
    imshow("img_thr_o", img_thr_o);
    imshow("img_thr_t", img_thr_t);
​
​
    //灰度图像自适应二值化
    Mat adaptive_mean, adaptive_gauss;
    adaptiveThreshold(img_thr, adaptive_mean, 255, ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,55,0);
    adaptiveThreshold(img_thr, adaptive_gauss, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 55, 0);
    imshow("adaptive_mean", adaptive_mean);
    imshow("adaptive_gauss", adaptive_gauss);
    waitKey(0);  
    return 0;
​
}
​

2.2.4 LUT像素灰度值映射

lut---灰度值映射

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    uchar lutFirst[256];
    for (int i = 0;i < 256;i++)
    {
        if (i < 100)
            lutFirst[i] = 0;
        if (i > 100 && i <= 200)
            lutFirst[i] = 100;
        if (i > 200)
            lutFirst[i] = 255;
​
    }
    Mat lutOne(1, 256, CV_8UC1, lutFirst);
​
​
    //lut第二层
    uchar lutSecond[256];
    for (int i = 0;i < 256;i++)
    {
        if (i < 100)
            lutSecond[i] = 0;
        if (i > 100 && i <= 150)
            lutSecond[i] = 100;
        if (i > 150&&i<200)
            lutSecond[i] = 150;
        if (i > 200)
            lutSecond[i] = 255;
    }
    Mat lutTwo(1, 256, CV_8UC1, lutSecond);
​
    //lut第三层
    uchar lutThird[256];
    for (int i = 0;i < 256;i++)
    {
        if (i < 100)
            lutThird[i] = 0;
        if (i > 100 && i <= 200)
            lutThird[i] = 200;
        if (i > 200)
            lutThird[i] = 255;
    }
    Mat lutThree(1, 256, CV_8UC1, lutThird);
​
​
    //拥有三通道的LUT矩阵
    // 
    vector<Mat> mergetMats;
    mergetMats.push_back(lutOne);
    mergetMats.push_back(lutTwo);
    mergetMats.push_back(lutThree);
    Mat LutTree;
    merge(mergetMats, LutTree);
​
​
    //计算图像查找表
    Mat img = imread("D:/classical.jpg");
    if (img.empty())
    {
        cout << "请重新输入图片路径" << endl;
        return-1;
    }
    Mat gray, out0, out1, out2;
    cvtColor(img,gray, COLOR_BGR2GRAY);
    LUT(gray, lutOne,out0);
    LUT(img, lutTwo, out1);
    LUT(img, LutTree, out2);
    imshow("out0",out0);
    imshow("out1",out1);
    imshow("out2", out2);
    waitKey(0);  
    return 0;
​
}
​
​

2.3图像变换

2.3.1图像连接

vaoncat()函数:

要求:Mat类型中具有相同的的列数并且具有相同的数据类型和通道数

原型1(纵向连接)的第二个参数:是数组中所有的Mat类型数据的数目

原型2(两个矩阵竖向连接)的第二个参数

hconcat()函数实现图像或者矩阵左右拼接:

这里先用矩阵来测试一下

//创建一个矩阵数组
    Mat matarray[] = {Mat(1,2,CV_32FC1,Scalar(1)),Mat(1,2,CV_32FC1,Scalar(2))};
    Mat vout, hout;
    vconcat(matarray,2,vout);
    cout << "图像数组竖起来连接" << endl << vout << endl;
​
    hconcat(matarray, 2, hout); 
​
​
    //矩阵的横竖拼接
    Mat A = (Mat_<float>(2, 2) << 1, 7, 2, 8);
    Mat B = (Mat_<float>(2, 2) << 4, 10, 5, 11);\
    Mat vc, hc;
    vconcat(A, B, vc);
    cout << "多个图像数组竖起来连接" << endl << vc<< endl;
​
    hconcat(A, B, hc);
    cout << "多个图像数组竖起来连接" << endl << hc << endl;

为了测试拼接效果我们先把他切成四份;

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
//切割成2*2个子图片
#define cut_rows 2   
#define cut_cols 2 
​
string num2str(int i)
{
​
    stringstream ss;
    ss << i;
    return ss.str();
}
​
void CutPics(string path, string fileTarget)
{
​
    Mat srcImg = imread(path);
​
    vector<Mat> ceilImg;
​
    int height = srcImg.rows;
    int width = srcImg.cols;
​
​
    int ceil_height = (int)(height / cut_rows);//总高度除以2,把高度分成几分
    int ceil_width = (int)(width / cut_cols);
    int ceil_down_height = height - (cut_rows - 1) * ceil_height;//
    int ceil_right_width = width - (cut_cols - 1) * ceil_width;
​
    for (int i = 0; i < cut_rows - 1; i++)
        for (int j = 0; j < cut_cols; j++)
        {
            if (j < cut_cols - 1)
            {
                Rect rect(j * ceil_width, i * ceil_height, ceil_width, ceil_height);
                ceilImg.push_back(srcImg(rect));
​
            }
            else
            {
                Rect rect((cut_cols - 1) * ceil_width, i * ceil_height, ceil_right_width, ceil_height);
                ceilImg.push_back(srcImg(rect));
            }
        }
​
    for (int i = 0; i < cut_cols; i++)
    {
        if (i < cut_cols - 1)
        {
            Rect rect(i * ceil_width, (cut_rows - 1) * ceil_height, ceil_width, ceil_down_height);
            ceilImg.push_back(srcImg(rect));
        }
        else   //右下角这个图像块
        {
            Rect rect((cut_cols - 1) * ceil_width, (cut_rows - 1) * ceil_height, ceil_right_width, ceil_down_height);
            ceilImg.push_back(srcImg(rect));
        }
    }
​
​
​
    cout << "分块个数:" << ceilImg.size() << endl;
    Mat dst;
​
​
​
    for (int i = 0; i < ceilImg.size(); i++)
    {
        dst = ceilImg[i];
​
        /*imwrite( "F:/pic/00.jpg", dst);*/
        imwrite("D:/"+ num2str(i + 1) + ".jpg", dst);
        cout << "保存成功" << endl;
        imshow("dst", dst);
​
        /*waitKey(0);*/
    }
​
    waitKey(0);
​
}
​
​
int main(int agrc,char ** agrv)
{
    string path = "D:/cuttest.jpg";
    string fileTarget = "savecut";
    CutPics(path, fileTarget);
    waitKey(0);  
    return 0;
​
}
​

这里对图片进行拼接:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    Mat img00 = imread("D:/1.jpg");
        
    Mat img01 = imread("D:/2.jpg");
    Mat img10 = imread("D:/3.jpg");
    Mat img11 = imread("D:/4.jpg");
​
    if (img00.empty() || img01.empty() || img10.empty() || img11.empty())
    {
        cout << "文件打开失败" << endl;
        return -1;
​
    }
​
    imshow("img00",img00);
    imshow("img01", img01);
    imshow("img10", img10);
    imshow("img11", img11);
    
    Mat img, img0,  img1;
​
    hconcat(img00, img01, img0);
    hconcat(img10,img11,img1);
    vconcat(img0,img1,img);
    imshow("img0", img0);
    imshow("img1", img1);
    imshow("img",img);
    waitKey(0);  
    return 0;
​
}
​

2.3.2图像尺寸变化

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
//切割成2*2个子图片
#define cut_rows 2   
#define cut_cols 2 
int main(int agrc,char ** agrv)
{
​
    Mat gray = imread("D:/cuttest.jpg",IMREAD_GRAYSCALE);
    if (gray.empty())
    {
        cout << "请输入正确的路径:" << endl;
    }
    Mat smallImg, bigImg0, bigImg1, bigImg2;
    resize(gray,smallImg,Size(15,15),0,0,INTER_AREA);
    resize(smallImg, bigImg0, Size(30, 30), 0, 0, INTER_AREA);
    resize(smallImg, bigImg1, Size(30, 30), 0, 0, INTER_LINEAR);
    resize(smallImg, bigImg2, Size(30, 30), 0, 0, INTER_CUBIC);
    namedWindow("smallimg",WINDOW_NORMAL);
    imshow("smallimg", smallImg);
​
    namedWindow("bigImg0",WINDOW_NORMAL);
    imshow("bigima0",bigImg0);
​
​
    namedWindow("bigImg1",WINDOW_NORMAL);
    imshow("bigImg1", bigImg1);
​
    namedWindow("bigima2",WINDOW_NORMAL);
    imshow("bigima2",bigImg2);
    waitKey(0);  
    return 0;
​
}
​
​

2.3.3图像的翻转

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    Mat img = imread("D:/cuttest.jpg",IMREAD_GRAYSCALE);
    if (img.empty())
    {
        cout << "请输入正确的路径:" << endl;
    }
    Mat img_x, img_y,img_xy;
    flip(img, img_x,0);
    flip(img,img_y,1);
    flip(img,img_xy,-1);
    imshow("img_x",img_x);
    imshow("img_y", img_y);
    imshow("img_xy", img_xy);
    waitKey(0);  
    return 0;
​
}
​

getRotationMatrix2D函数:

输入旋转角和旋转中心,输出图像旋转矩阵

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
//切割成2*2个子图片
#define cut_rows 2   
#define cut_cols 2 
​
int main(int agrc,char ** agrv)
{   
    Mat img = imread("D:/测试照片/cuttest.jpg");
    if (img.empty())
    {
        cout << "请输入正确的路径:" << endl;
    }
    Mat rotation0, rotation1,img_warp0,img_warp1;
    double angle = 30;
    Size dst_size(img.rows,img.cols);
    Point2f center(img.rows/2, img.cols/2);
    rotation0 = getRotationMatrix2D(center,angle,1);//变换矩阵
    warpAffine(img, img_warp0, rotation0, dst_size);
    imshow("img_warp0", img_warp0);
    //根据定义的三个点进行仿射变换
    Point2f src_points[3];
    Point2f dst_points[3];
    src_points[0] = Point2f(0, 0);
    src_points[1] = Point2f(0, (float)(img.cols - 1));
    src_points[2] = Point2f((float)(img.rows - 1), (float)(img.cols - 1));
    dst_points[0] = Point2f((float)(img.rows)*0.11, (float)(img.cols)*0.2);
    dst_points[1] = Point2f((float)(img.rows) * 0.15, (float)(img.cols) * 0.7);
    dst_points[2] = Point2f((float)(img.rows) * 0.81, (float)(img.cols) * 0.85);
​
    //根据对应点求仿射变换矩阵、
    rotation1 = getAffineTransform(src_points, dst_points);
    warpAffine(img, img_warp1, rotation1, dst_size);
​
    imshow("img_warp1", img_warp1);
    waitKey(0);  
    return 0;
​
}
​
​

2.3.4图像透视变换

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
​
int main(int agrc,char ** agrv)
{
    Mat img = imread("D:/测试照片/qcode.jpg");
    cout << "正在" << endl;
    if (img.empty())
    {
        cout << "请输入正确的路径:" << endl;
    }
    //根据定义的三个点进行仿射变换
    Point2f src_points[4];
    Point2f dst_points[4];
    src_points[0] = Point2f(325.0,462.0);
    src_points[1] = Point2f(594.0,493.0);
    src_points[2] = Point2f(431.0,233.0);
    src_points[3] = Point2f(697.0,253.0);
​
    dst_points[0] = Point2f(0.0,0.0);
    dst_points[1] = Point2f(620.0,0.0);
    dst_points[2] = Point2f(0.0,620.0);
    dst_points[3] = Point2f(620.0, 620.0);
    //根据对应点求仿射变换矩阵、
​
    Mat rotation, img_warp;
    rotation = getPerspectiveTransform(src_points, dst_points);
    warpPerspective(img,img_warp,rotation,img.size());
    imshow("img", img);
    imshow("img_warp", img_warp);
​
    waitKey(0);  
    return 0;
​
}

2.3.5极坐标变换

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
int main(int agrc,char ** agrv)
{
    Mat img = imread("D:/测试照片/cuttest.jpg");
    cout << "正在" << endl;
    if (img.empty())
    {
        cout << "请输入正确的路径:" << endl;
    }
​
    Mat img1, img2;
    Point2f center = Point2f(img.cols / 2, img.rows / 2);
    //正极坐标转换
    warpPolar(img, img1, Size(300, 600), center, center.x,INTER_LINEAR+WARP_POLAR_LINEAR);
    //逆极坐标转换
    warpPolar(img1, img2, Size(img.rows, img.cols),center, center.x, INTER_LINEAR + WARP_POLAR_LINEAR + WARP_INVERSE_MAP);
    imshow("原始表盘",img);
    imshow("表盘极坐标变换结果",img1);
    imshow("逆变换的结果", img2);
    imshow("img", img);
​
    waitKey(0);   
​
}

2.4绘制图像

circle:画圆函数

line:画直线

ellipse:画椭圆

ellipse2Poly:画椭圆

rectangle:画矩形 fillPoly:画多边形

putText():生成文字

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int main(int agrc,char ** agrv)
{
    Mat img = Mat::zeros(Size(512, 512), CV_8UC3);
    //绘制圆
    circle(img, Point(50, 50), 25, Scalar(255, 255, 255), -1);
    circle(img, Point(100, 50), 25, Scalar(255, 255, 255), 4);
    //绘制直线
    line(img, Point(100, 100), Point(200, 100), Scalar(255, 255, 255), 2, LINE_4, 0);
        //绘制椭圆
    ellipse(img, Point(300, 255), Size(100, 70), 0, 0, 100, Scalar(255, 255, 255), -1);
    ellipse(img, RotatedRect(Point2f(150, 100), Size2f(30, 20), 0), Scalar(255, 255, 255), 2);
    //用一些点来近似一个椭圆
    vector<Point>points;
    ellipse2Poly(Point(200,400),Size(100,70),0,0,360,2,points);
    for (int i=0;i<points.size()-1;i++)
    {
        if (i == points.size() - 1)
        {
            //椭圆最后一个点与第一个点连线
            line(img, points[0], points[i], Scalar(255, 255, 255), 2);
            break;
        }
        line(img, points[i], points[i + 1], Scalar(255, 255, 255), 2);
    }
​
    //绘制矩形
    rectangle(img, Point(50, 400), Point(100, 450), Scalar(255, 255, 255), 2);
    //写入文字
    putText(img,"lear opencv",Point(105,400),2,1,Scalar(255,255,255));
    imshow("img", img);
    waitKey();
    return 0;
​
}
​
​

2.5感兴趣的区域拷贝

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
int main(int agrc,char ** agrv)
{
    Mat img = imread("D:/测试照片/cuttest.jpg");
    Mat noobcv = imread("D:/测试照片/beauty.jpg");
    if (img.empty() || noobcv.empty())
    {
        cout << "文件名称错误" << endl;
        return -1;
    }
    Mat ROI1, ROI2, ROI2_copy, mask, img2,img_copy, img_copy2;
    resize(noobcv, mask, Size(200, 200));//压缩
    img2 = img;//浅拷贝
    //深拷贝的两种方式
    img.copyTo(img_copy2);
    copyTo(img, img_copy, img);
​
    //两种截图方式
    Rect rect(206, 206, 200, 200);
    ROI1 = img(rect);
    ROI2 = img(Range(300, 700), Range(300, 700));//第二种截图方法
​
    img(Range(300,600),Range(300,600)).copyTo(ROI2_copy);
​
    imshow("img", img);
    imshow("ROI2", ROI2);
    imshow("ROI2_copy", ROI2_copy);
    circle(img, Point(300, 300), 20, Scalar(0, 0, 255), - 1);
    mask.copyTo(ROI1);
    imshow("img", img); 
    imshow("浅拷贝的img", img2);
    imshow("ROI1", ROI1);
    imshow("ROI2", ROI2);
    imshow("ROI2_copy", ROI2_copy);
    waitKey();
    return 0;
​
}
​

2.6图像金字塔

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
​
int main(int agrc,char ** agrv)
{
    Mat img = imread("D:/测试照片/classical.jpg");
    if (img.empty() )
    {
        cout << "文件名称错误" << endl;
        return -1;
    }
    vector<Mat>Gauss, Lap;
    int leve=3;//设置采样数
    Gauss.push_back(img);
    //构建高斯金字塔
    for (int i=0;i< leve;i++)
    {
        Mat gauss;
        cout << "构建高斯金字塔" << endl;
        pyrDown(Gauss[i], gauss);
        Gauss.push_back(gauss);
    }
    //构建拉普拉斯金字塔
    for (int i=Gauss.size()-1;i>0;i--)
    {
        cout << "构建拉普拉斯金字塔" << endl;
        Mat lap, upGauss;
        if (i==Gauss.size()-1)
        {
            Mat down;
            pyrDown(Gauss[i], down);
            pyrUp(down,upGauss);
            lap = Gauss[i] - upGauss;
            Lap.push_back(lap);
        }
        pyrUp(Gauss[i],upGauss);
        lap = Gauss[i-1] - upGauss;
        Lap.push_back(lap);
    }
    //查看两个图像金字塔种的图像
    for (int i=0;i<Gauss.size();i++)
    {
        cout << "读取图像" << endl;
        string name = to_string(i);
        imshow("G" + name, Gauss[i]);
        imshow("L" + name, Lap[i]);
    }
    waitKey(0);
    return 0;
​
}

2.7窗口交互操作

2.7.1.窗口滑动条

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int value;
void callBack(int,void*);
​
Mat img1, img2;
​
int main(int agrc,char ** agrv)
{
    img1 = imread("D:/测试照片/classical.jpg");
    if (!img1.data )
    {
        cout << "文件名称错误" << endl;
        return -1;
    }
    namedWindow("滑动条改变图像亮度");
    imshow("滑动条改变图像亮度",img1);
    value = 100;
    createTrackbar("亮度值百分比", "滑动条改变图像亮度", &value, 600, callBack, 0);
    waitKey(0);
​
​
}
static void callBack(int ,void*)
{
    float a = value / 100.0;
    img2 = img1 * a;
    imshow("滑动条改变图像亮度",img2);
}
​
​

2.7.2鼠标响应

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
typedef unsigned char uchar;
using namespace cv;
using namespace std;
​
int value;
void callBack(int,void*);
​
Mat img, imgPoint;
Point prePoint;
void mouse(int event,int x,int y,int flags,void*);
​
int main(int agrc,char ** agrv)
{
    img = imread("D:/测试照片/classical.jpg");
    if (!img.data )
    {
        cout << "文件名称错误" << endl;
        return -1;
    }
    img.copyTo(imgPoint);
    imshow("图像窗口1",img);
    imshow("图像窗口2",img);
    setMouseCallback("图像窗口1", mouse, 0);
    waitKey(0);
    return 0;
}
void mouse(int event,int x,int y,int flags,void *)
{
    imgPoint.at<Vec3b>(y, x) = Vec3b(0, 0, 255);
    imgPoint.at<Vec3b>(y, x - 1) = Vec3b(0, 0, 255);
    imgPoint.at<Vec3b>(y, x + 1) = Vec3b(0, 0, 255);
    imgPoint.at<Vec3b>(y+1, x ) = Vec3b(0, 0, 255);
    imgPoint.at<Vec3b>(y+1, x) = Vec3b(0, 0, 255);
    imshow("图像窗口2", imgPoint);
    Point pt(x, y);
    line(img, prePoint, pt, Scalar(0, 0, 255), 2, 3, 0);
    prePoint = pt;
    imshow("图像窗口1",img);
}
​
​

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知新_ROL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值