OpenCV掩码、blending、改变对比度和亮度、随机发生器和绘图

掩码

一般来说是对某个像素邻域内的几个像素进行相应的操作实现对图像的滤波等操作。

0-10
-15-1
0-10

例如上面的这个掩码核,使用它来对整副图像进行操作。具体代码如下:

 const uchar* pre;
    const uchar* courrent;
    const uchar* next;
    for(int i = 1;i < height-1;i++)
    {
        pre = src.ptr<uchar>(i-1);
        courrent = src.ptr<uchar>(i);
        next = src.ptr<uchar>(i+1);
        for(int j = 1;j < width-1;j++)
        {   
            dst.at<uchar>(i,j) = saturate_cast<uchar>(5*courrent[j]-courrent[j-1]-courrent[j+1]-pre[j]-next[j]);
        }
    }

同样OpenCV给们提供了相应的api使用,不用自己去一点点敲

Mat kernel = (Mat_<char>(3,3) << 0,-1,0,-1,5,-1,0,-1,0);
    filter2D(src,api_dst,src.depth(),kernel);

效果是一样的。

Blending

两幅图像进行叠加:
g(i,j) = a*f1(i,j) + (1-a)f2(i,j) + b
分为两种情况:

  • 两幅图像大小不同,首先对一个图像进行resize,化为两个大小一样,然后在相叠加。
  • 两幅图像大小不同,将小的图像直接叠加在大图的某一区域。

第一种情况:
两个大小不一样

  	resize(icon,icon,Size(map.cols,map.rows));
  	const Vec3b* map_ptr;
    const Vec3b* icon_ptr;
    Vec3b* result_ptr; 
    for(int i = 0;i < map.rows-1;i++)
    {   
        map_ptr = map.ptr<Vec3b>(i);
        icon_ptr = icon.ptr<Vec3b>(i);
        result_ptr = result.ptr<Vec3b>(i);
        for(int j = 0;j < map.cols-1;j++)
        {
            result_ptr[j][0] = saturate_cast<uchar>(map_ptr[j][0]*0.3+icon_ptr[j][0]*0.7);
            result_ptr[j][1] = saturate_cast<uchar>(map_ptr[j][1]*0.3+icon_ptr[j][1]*0.7);
            result_ptr[j][2] = saturate_cast<uchar>(map_ptr[j][2]*0.3+icon_ptr[j][2]*0.7);
        }
    }

同样的OpenCV提供了相应的API:

resize(icon,icon,Size(map.cols,map.rows));
addWeighted(map,0.3,icon,0.7,0,result);

第二种情况相对来说实现其来相对来所比较复杂,所以专门写一个函数来进行操作:

Mat Add(const Mat src1,float bate,const Mat src2,float alpha,int x,int y,int width,int height)
{
    Mat result;
    src1.copyTo(result);
    const Vec3b* ptr1;
    const Vec3b* ptr2;
    Vec3b* result_ptr;
    for(int i = 0;i< height-1;i++)
    {
        ptr1 = src1.ptr<Vec3b>(i+y);
        ptr2 = src2.ptr<Vec3b>(i);
        result_ptr = result.ptr<Vec3b>(i+y);
        for(int j = 0;j < width-1;j++)
        {
            result_ptr[j+x][0] = saturate_cast<uchar>(ptr1[j+x][0]*bate + ptr2[j][0]*alpha);
            result_ptr[j+x][1] = saturate_cast<uchar>(ptr1[j+x][1]*bate + ptr2[j][1]*alpha);
            result_ptr[j+x][2] = saturate_cast<uchar>(ptr1[j+x][2]*bate + ptr2[j][2]*alpha);
        }
    }
    return result;
}

同样的,也有相应的API:

  	Mat imageROI;
    imageROI = map(Rect(20,20,icon.cols,icon.rows));
    addWeighted(icon,0.5,imageROI,0.5,0,imageROI);
    imshow("result1",map);

改变对比度和亮度

g(i,j) = a* f(i,j) + b
a值用来改变图像的对比度,b值用来改变图像的亮度。
同样的,自定义一个函数来进行对比度和亮度的改变。

Mat Change(const Mat src,float bate,float alpha)
{
    Mat result = Mat::zeros(src.size(),src.type());
    const Vec3b* ptr;
    Vec3b* res_ptr;
    for(int row = 0;row < src.rows - 1;row++)
    {
        ptr = src.ptr<Vec3b>(row);
        res_ptr = result.ptr<Vec3b>(row);
        for(int col = 0;col < src.cols - 1;col++)
        {
            res_ptr[col][0] = saturate_cast<uchar>(ptr[col][0] * bate + alpha);
            res_ptr[col][1] = saturate_cast<uchar>(ptr[col][1] * bate + alpha);
            res_ptr[col][2] = saturate_cast<uchar>(ptr[col][2] * bate + alpha);
        }
    }
    return result;
}

同样的,也有相应的API供我们使用:

	map.convertTo(map,-1,1.0,100);
    imshow("map2",map);

随机发生器和绘图

随机发生器:

RNG rng(0xffffffff);定义随机发生器的对象,并用0xffffffff来进行初始化。
int x = rng.uniform(start,end);

绘制直线:

line(image,开始点,结束点,Scalar(0,0,0),线宽,类型=8连续);

绘制矩形:

rectangle(image,左上顶点,右下顶点,Scalar(0,0,0),线宽=-1填充,类型=8连续);

有代码如下:

	RNG rng(0xffffffff);

    Mat image = Mat::zeros(500,500,CV_8UC3);
    imshow("image",image);
    Scalar color ;
    Point start_p,end_p;
    for(int i  = 0;i < 100;i++)
    {
        color = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
        start_p.x = rng.uniform(0,500);
        start_p.y = rng.uniform(0,500);
        end_p.x = rng.uniform(0,500);
        end_p.y = rng.uniform(0,500);
        rectangle(image,start_p,end_p,color,-1,8);
    }
    imshow("image",image);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值