opencv学习笔记(2)

1、Mat通道的分离与合并

多通道Mat分离为vector数组,vector数组可以合并为多通道Mat

vector< cv::Mat > mv;
cv::split(lab, mv); //分离
cv::merge(mv, lab);//合并

2、图片的深拷贝和浅拷贝

1)浅拷贝:

Mat B;  
B = image  // 第一种方式  
Mat C(image); // 第二种方式

这两种方式称为浅copy,是由于它们有不同的矩阵头,但是它们共享内存空间,即指向一个矩阵。当图像矩阵发生变化时,两者相关联,都会变化。

2)深拷贝

Mat B,C;  
B = image.clone();       // 第一种方式  
image.copyTo(C); // 第二种方式  

深拷贝是真正的copy了一个新的图像矩阵,此时image,B,C三者相互没有影响。

转载此处

3、图像的拼接(横向和纵向)

// 图像拼接
cv::Mat ImageSplicing(vector<cv::Mat> images,int type)
{
    if (type != 0 && type != 1)
        type = 0;

    int num = images.size();
    int newrow = 0;
    int newcol = 0;
    cv::Mat result;

    // 横向拼接
    if (type == 0)
    {
        int minrow = 10000;

        //1、获取行最小值
        for (int i = 0; i < num; ++i)
        {
            if (minrow > images[i].rows)
                minrow = images[i].rows;
        }
        newrow = minrow;

        //2、利用行最小值调整图片大小、统一图片类型
        for (int i = 0; i < num; ++i)
        {
            int tcol = images[i].cols*minrow / images[i].rows;
            int trow = newrow;
            cv::resize(images[i], images[i], cv::Size(tcol, trow));
            newcol += images[i].cols;
            if (images[i].type() != images[0].type())
                images[i].convertTo(images[i], images[0].type());//数据类型转换
        }

        //3、创建拼图的mat
        result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));

        cv::Range rangerow, rangecol;
        int start = 0;
        for (int i = 0; i < num; ++i)
        {
            rangerow = cv::Range((newrow - images[i].rows) / 2, (newrow - images[i].rows) / 2 + images[i].rows);
            rangecol = cv::Range(start, start + images[i].cols);
            images[i].copyTo(result(rangerow, rangecol)); //将image[i]复制到result的指定范围内
            start += images[i].cols;
        }
    }
    // 纵向拼接
    else if (type == 1) {
        int mincol = 10000;
        for (int i = 0; i < num; ++i)
        {
            if (mincol > images[i].cols)
                mincol = images[i].cols;
        }
        newcol = mincol;
        for (int i = 0; i < num; ++i)
        {
            int trow = images[i].rows*mincol / images[i].cols;
            int tcol = newcol;
            cv::resize(images[i], images[i], cv::Size(tcol, trow));
            newrow += images[i].rows;
            if (images[i].type() != images[0].type())
                images[i].convertTo(images[i], images[0].type());
        }
        result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));

        cv::Range rangerow, rangecol;
        int start = 0;
        for (int i = 0; i < num; ++i)
        {
            rangecol= cv::Range((newcol - images[i].cols) / 2, (newcol - images[i].cols) / 2 + images[i].cols);
            rangerow = cv::Range(start, start + images[i].rows);
            images[i].copyTo(result(rangerow, rangecol));
            start += images[i].rows;
        }
    }

    return result;
}

转载此处

4、图像的加权混合(两张图片的透明度不同)

函数是将两张相同大小,相同类型的图片(叠加)线性融合的函数,可以实现图片的特效。
算子:g(x)=(1−α)f0(x)+αf1(x)

Mat dst;
addWeighted(image1, alpha, image2, (1 - alpha), 0, dst, -1);
imshow("dst", dst);

5、图像的亮度、对比度调节

算子:g(i,j)=αf(i,j)+β //α亮度 β对比度

此操作需要访问图像的每一个元素:
方法一:下标遍历法,格式为M.at< typede>(i,j)

if (channel == 3) {
		for (int h = 0; h < height; h++) {
			for (int w = 0; w < width; w++) {
				dst_at.at<Vec3b>(h, w)[0] = saturate_cast<uchar>(image32f.at<Vec3f>(h, w)[0] * alpha + beta);
				dst_at.at<Vec3b>(h, w)[1] = saturate_cast<uchar>(image32f.at<Vec3f>(h, w)[1] * alpha + beta);
				dst_at.at<Vec3b>(h, w)[2] = saturate_cast<uchar>(image32f.at<Vec3f>(h, w)[2] * alpha + beta);
			}
		}
	}

saturate_cast: 在图像处理方面,无论是加是减,乘除,都会超出一个像素灰度值的范围(0~255),saturate_cast函数的作用即是:当运算完之后,结果为负,则转为0,结果超出255,则为255。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值