OpenCV基础API函数二

OpenCV基础API函数一

OpenCV基础API函数二

OpenCV基础API函数三

OpenCV基础API函数四

OpenCV基础API函数五

setMouseCallback 鼠标响应事件

void setMouseCallback(const String &winname, MouseCallback onMouse, void *userdata = 0);

返回值: 空
winname: 显示窗口的名字
onMouse: 鼠标响应回调函数
userdata: 给鼠标回调函数传递的任意类型的数据

回调函数的定义
void (*MouseCallback)(int event, int x, int y, int flags, void *userdata);

返回值:空
event: 鼠标事件 枚举类型
x: 鼠标在图片中x坐标
y:鼠标在图片中y坐标
flags: 标志位
userdata: 使用的资源

envnet 常用的类型

even 类型t意思
EVENT_MOUSEMOVE鼠标移动
EVENT_LBUTTONDOWN鼠标左键按下
EVENT_RBUTTONDOWN鼠标右键按下
EVENT_MBUTTONDOWN鼠标滚轮按下
EVENT_LBUTTONUP鼠标左键抬起
EVENT_RBUTTONUP鼠标右键抬起
EVENT_MBUTTONUP鼠标滚轮抬起
EVENT_LBUTTONDBLCLK鼠标左键双击
EVENT_RBUTTONDBLCLK鼠标右键双击
EVENT_MBUTTONDBLCLK鼠标滚轮双击
EVENT_MOUSEWHEEL鼠标滚轮滑动,flags>0向前滚动,flags<0向后滚动

例子 截取鼠标选中的矩形块

Point moveP(-1, -1);
Point downP(-1, -1);
int A=0;

//鼠标回调函数
void mouseMove(int event, int x, int y, int flags, void *userdata)
{
    //把任意类型的数据转换成Mat类型
    Mat src = *((Mat *) userdata);
    //把src原图像克隆给dec
    Mat dec = src.clone();
    Mat dst;
    //鼠标移动事件
    if (event == EVENT_MOUSEMOVE)
    {
        moveP.x = x;
        moveP.y = y;
        //当左键按下,画出矩形块
        if (downP.x != -1)
        {
            //定义矩形
            Rect rect(downP,moveP);
            rectangle(dec, rect, Scalar(0, 0, 255), 3);
            imshow("输出窗口", dec);
        }
        cout << "x " << moveP.x << " y " << moveP.y << endl;
    }
    //鼠标左键按下
    if (event == EVENT_LBUTTONDOWN)
    {
        downP.x = x;
        downP.y = y;
        cout << "x " << downP.x << " y " << downP.y << endl;
    }
    //鼠标左键抬起
    if (event == EVENT_LBUTTONUP)
    {

        //校验鼠标坐标是否在图片范围内
        if (moveP.x >= src.cols)
        {
            moveP.x = src.cols;
        }
        if (moveP.y >= src.rows)
        {
            moveP.y = src.rows;
        }
        if (moveP.x <= 0)
        {
            moveP.x = 0;
        }
        if (moveP.y <= 0)
        {
            moveP.y = 0;
        }
        Rect rect1(downP, moveP);
        namedWindow("提取");
        imshow("提取", dec(rect1));
        downP.x = -1;
        downP.y = -1;

    }


    if (event == EVENT_MOUSEWHEEL)
    {
        cout << "我是flage" << flags << endl;
        //向前滚动
        if (flags > 0)
        {
            A++;
            resize(src, dst, Size(src.rows + A, src.cols + A));

        } else
        {
            A--;
            resize(src, dst, Size(src.rows + A, src.cols + A));
        }
//        cout << "srcRows " << srcRows << " srcCols " << srcCols << endl;
        imshow("图片缩放", dst);
    }

}

//鼠标事件
void mouseEvent(Mat &src)
{
    namedWindow("输出窗口", WINDOW_FREERATIO);
    setMouseCallback("输出窗口", mouseMove, &src);
    imshow("输出窗口", src);
}

flip 图像翻转

void flip(InputArray src, OutputArray dst, int flipCode);

返回值:空
src: 原图像
dst: 结果图像
flipCode: 翻转类型 flipCode<0 旋转180度 

flipCode 类型

flipCode意思
flipCode<0旋转180度
flipCode=0图像上下翻转
flipCode>0图像左右翻转

例子: 翻转图像
在这里插入图片描述

void myFlip(Mat &src){
    Mat dst;
    flip(src, dst, -1);
    imshow("旋转180", dst);
    flip(src, dst, 0);
    imshow("图像上下翻转", dst);
    flip(src, dst, 1);
    imshow("图像左右翻转", dst);

}

warpAffine 仿射变换

void warpAffine( InputArray src, OutputArray dst,
                              InputArray M, Size dsize,
                              int flags = INTER_LINEAR,
                              int borderMode = BORDER_CONSTANT,
                              const Scalar& borderValue = Scalar());
返回值: 空
src: 原图片
dst: 结果图片
M : 仿射变换的变换矩阵  
dsize :结果图片的大小
flags: 内插值类型
borderMode: 变换过后边界的类型
borderValue: 边界的颜色

仿射变换的公式
在这里插入图片描述
利用上述公式可以实现图片的平移,旋转,缩放,剪切等四种变换
其中A就是我们的API中的M
在这里插入图片描述
例子: 关于中心旋转
在这里插入图片描述

void myRotate(Mat &src)
{
    //结果图片
    Mat dst;
    //仿射变换的矩阵
    Mat M;
    //图片的宽和高
    double rows = src.rows;
    double cols = src.cols;
    /*
     * 获得旋转的仿射变换矩阵
     * 第一个参数表示: 绕那个点进行旋转,这里选择中心点
     * 第二个参数表示: 旋转多少度   angle>0表示逆时针旋转 angle<0表示顺时针旋转
     * 第三个参数表示: 结果图片是否进行缩放
     *返回结果:是一个3X3的矩阵,参考上图(关于原点)选择的仿射矩阵A
     **/
    M = getRotationMatrix2D(Point2f(rows / 2, cols / 2), 45, 1.0);

    //计算新图像的长宽高
    double cos$ = abs(M.at<double>(0, 0));
    double sin$ = abs(M.at<double>(0, 1));
    double newRow = rows * cos$ + cols * sin$;
    double newCol = cols * cos$ + rows * sin$;
    //新图像的中心点
    M.at<double>(0, 2) += (newRow - rows) / 2.0;
    M.at<double>(1, 2) += (newCol - cols) / 2.0;
    //进行仿射变换
    warpAffine(src, dst, M, Size(newRow, newCol));
    imshow("仿射变换", dst);
//缩放
    Mat transform_scale = Mat::zeros(2, 3, CV_64F);
    transform_scale.at<double>(0,0)=0.8;
    transform_scale.at<double>(1,1)=0.8;
    warpAffine(src, dst, transform_scale, Size(rows, cols), INTER_AREA, BORDER_CONSTANT, Scalar(0, 255, 255));
    imshow("仿射变换--缩放", dst);

    //平移
    Mat transform_T = Mat::zeros(2, 3, CV_64F);
    transform_T.at<double>(0,0)=1;
    transform_T.at<double>(1,1)=1;
    transform_T.at<double>(0,2)=100;
    transform_T.at<double>(1,2)=100;
    warpAffine(src, dst, transform_T, Size(rows, cols), INTER_AREA, BORDER_CONSTANT, Scalar(0, 255, 255));
    imshow("仿射变换--平移", dst);
    
    //剪切
    Mat transform_C = Mat::zeros(2, 3, CV_64F);
    transform_C.at<double>(0,0)=1;
    transform_C.at<double>(1,1)=1;
    transform_C.at<double>(1,0)=0.5;
    transform_C.at<double>(0,1)=0.5;

    warpAffine(src, dst, transform_C, Size(rows, cols), INTER_AREA, BORDER_CONSTANT, Scalar(0, 255, 255));
    imshow("仿射变换--剪切", dst);
    return ;
    return ;
}

calcHist 直方图

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:若要计算整个图像则mask=Mat()空图像,若要计算一部分图像则需要不为空
hist:输出的结果
dims:直方图的维数
histSize:直方图的个数(若是柱形图则表示有几个柱形,折线图则表示有几个转折点)
ranges:统计灰度的范围
uniform:是否对得到的直方图数组进行归一化处理 默认为true
accumulate :在多个图像时,是否累计计算像素值得个数  默认为false

例子: 统计GBR的直方图
在这里插入图片描述

void newMyhistogram(Mat &src)
{
    //分离通道
    vector<Mat> bgr_plane;
    split(src, bgr_plane);
    //柱状图的个数
    const int binSize[1] = {255};
    //统计灰度的范围
    float hRanges[2] = {0, 255};
    const float *ranges[1] = {hRanges};
    
    //得到的GBR的灰度统计的直方图
    Mat b_hist;
    Mat g_hist;
    Mat r_hist;
    calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, binSize, ranges);
    calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, binSize, ranges);
    calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, binSize, ranges);

    //创建输出图像
    int hist_w = 512;
    int hist_h = 400;
    int bin_w = cvRound((double) hist_w / binSize[0]);
    Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);

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

    //绘制 直方图
    for (int i = 0; i < 256; i++)
    {
        line(histImage, Point(bin_w * i, cvRound((double) hist_h - b_hist.at<float>(i))),
             Point(bin_w * (i + 1), cvRound((double) hist_h - b_hist.at<float>(i + 1))),
             Scalar(255, 0, 0), 2, LINE_8,0);
        line(histImage, Point(bin_w * i, cvRound((double) hist_h - g_hist.at<float>(i))),
             Point(bin_w * (i + 1), cvRound((double) hist_h - g_hist.at<float>(i + 1))),
             Scalar(0, 255, 0), 2, LINE_8,0);
        line(histImage, Point(bin_w * i, cvRound((double) hist_h - r_hist.at<float>(i))),
             Point(bin_w * (i + 1), cvRound((double) hist_h - r_hist.at<float>(i + 1))),
             Scalar(0, 0, 255), 2, LINE_8,0);
        cout << "我是数值 " << b_hist.at<float>(i) << endl;
    }
    imshow("直方图", histImage);
}

equalizeHist 直方图均值化

void equalizeHist( InputArray src, OutputArray dst );

返回值:空
src: 原图像
dst: 结果图像

例子: 把一张暗图像进行均衡化,来提高对比度暴露更多细节
在这里插入图片描述

void eqmynewHistorgram(Mat &src)
{
    //转换成灰度图像
    cvtColor(src, src, COLOR_BGR2GRAY);
    Mat dst;
    //直方图均衡化
    equalizeHist(src, dst);
    namedWindow("直方图均值化", WINDOW_FREERATIO);
    imshow("直方图均值化", dst);
}

直方图均值化有利于提高图像的对比度,为了证明这一说法我们来看一组图片
在这里插入图片描述
从上述的图片当中,我们可以看高对比度的直方图的像素灰度值分布的比较均已,而我们的直方图均衡化就是把我们的原图像素灰度值进行均衡化

GaussianBlur 高斯模糊

void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
double sigmaX, double sigmaY = 0,
int borderType = BORDER_DEFAULT );

返回值: 空
src:原图像
dst: 结果图像
ksize:模糊窗口的大小
sigmaX: X轴方向的卷积核标准差
sigmaY: Y轴方向的卷积核标准差,默认为零表示X=Y,当sigmaX,sigmaY同时为零的时候会从ksize中进行推算出sigmaX,sigmaY,
borderType: 边界处理方式

例子:利用你高斯模糊处理图片
在这里插入图片描述

void Demo::Gaussian_Blur(Mat &src){
    Mat dst;
    GaussianBlur(src, dst, Size(17, 17), 3);
    imshow("高斯模糊", dst);
    GaussianBlur(src, dst, Size(17, 17), 13);
    //ksize或sigmaX,sigmaY越大模糊程度越大
    imshow("高斯模糊1", dst);
}

bilateralFilter 双边模糊–美颜效果

void bilateralFilter( InputArray src, OutputArray dst, int d,
double sigmaColor, double sigmaSpace,
int borderType = BORDER_DEFAULT );

返回值:空
src:输入的原图像
dst:结果图像
d: 模糊的窗口的大小,如果为零 则从sigmaSpace中计算得出
sigmaColor:颜色控件的卷积核标准差
sigmaSpace:xy空间上面的卷积和标准差,当d>0不考虑sigmaSpace的大小
borderType :边界处理的模式

例子: 利用双边模糊对任务进行美颜
在这里插入图片描述

void Demo::mybilateralFilter(Mat &src){
    Mat dst;
    //双边模糊
    bilateralFilter(src,dst,0,100,10);
    imshow("高斯双边模糊1", dst);
}

相对于高斯模糊和均值模糊双边模糊有一个更大的优点,就是他能够保留图片中的边界 而不会把边界进行模糊从而达到美颜的效果

blur 卷积模糊

void blur( InputArray src, OutputArray dst,
Size ksize, Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT );

返回值: 空
src:输入的圆图像
dst: 输出的结果图像
ksize: 卷积核的大小
anchor:卷积核的锚定点(中心点)
borderType: 边界处理模式

例子 对图像进行模糊

在这里插入图片描述

 	Mat dst;
    blur(src, dst, Size(9, 9));
    imshow("卷积模糊", dst);

卷积模糊边界处理的方法

borderType意思
BORDER_CONSTANT

持续更新中....请各位大佬多多指点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

~搬~运~工~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值