openCV学习记录:滤镜:碎片&暗调

来源:互联网 发布:冰箱哪个牌子好 知乎 编辑:程序博客网 时间:2024/06/17 07:04

碎片滤镜

Photoshop软件有一个碎片滤镜。我在实现碎片滤镜的过程中,发现只要改几个数就可以实现图像重影的效果。

将图像创建四个相互偏移的副本,叠加之后产生类似重影的效果。偏移方向为左上,左下,右上,右下,偏移角度为45度。将四个方向的偏移量累加求平均值作为中心点像素的值。各个方向的偏移量可以相同也可以不同。先来看相同的情况。

假如四个方向都偏移4个像素大小:

完整代码如下:

#include<opencv2/opencv.hpp>#include <iostream>using namespace cv;using namespace std;void chongYingFilter(Mat &srcImage);int main(){    Mat srcImage = imread("lena.jpg");//图片在工程目录下,否则写绝对路径    if(!srcImage.data || srcImage.empty()){        cout<<"读入图片错误!"<<endl;        return -1;    }    imshow("原图",srcImage);    chongYingFilter(srcImage);    waitKey(0);    return 0;} void chongYingFilter(Mat &srcImage){    //偏移量两两配合,分别是左下,左上,右上,右下    int OffsetJ[4] = { 4, -4, -4, 4 };    int OffsetI[4] = { -4, -4, 4, 4 };    int sumB,sumG,sumR;    for(int j = 0;j<srcImage.rows;j++){        for(int i = 0;i<srcImage.cols;i++){            sumB = 0;sumG = 0;sumR = 0;            for(int k = 0;k<4;k++){                int JJ = j + OffsetJ[k];                int II = i + OffsetI[k];                //防止越界                if(JJ < 0){                    JJ = 0;                }else if(JJ >= srcImage.rows){                    JJ = srcImage.rows - 1;                }                if(II < 0){                    II = 0;                }else if(II >= srcImage.cols){                    II = srcImage.cols - 1;                }                //累加,求当前像素点的左下,左上,右上,右下四个偏移量的和                sumB += srcImage.at<Vec3b>(JJ,II)[0];                sumG += srcImage.at<Vec3b>(JJ,II)[1];                sumR += srcImage.at<Vec3b>(JJ,II)[2];            }            //求平均值,求平均值(sum+2)/4,            //为什么要+2,就为了四舍五入。比如如果计算结果为108.6,则取像素109更为合理                 srcImage.at<Vec3b>(j,i)[2] = (sumR+2)>>2;            srcImage.at<Vec3b>(j,i)[1] = (sumG+2)>>2;            srcImage.at<Vec3b>(j,i)[0] = (sumB+2)>>2;        }    }    imshow("重影滤镜",srcImage);}

效果如下图:
这里写图片描述

如果把偏移量调大呢?比如每个方向都是16个像素大小

int OffsetJ[4] = { 16, -16, -16, 16 };int OffsetI[4] = { -16, -16, 16, 16 };

效果图如下:

这里写图片描述

如果只把一个方向的偏移量调大,其余三个一样大呢:

int OffsetJ[4] = { 6, -6, -6, 6 };int OffsetI[4] = { -66, -6, 6, 6 };

这事产生重影,效果图如下:
这里写图片描述

如果想重影是上下方向呢?就像下图那样:

这里写图片描述

那就这样调偏移量:

int OffsetJ[4] = { 6, -6, -6, 66 };int OffsetI[4] = { -6, -6, 6, 6 };



总结:还有其他变化吗?
当然,比如右下方向的偏移量比其他三个都要大,又会产生新的重影图像,亦或者把偏移数目调成8个,再增加上下左右四个偏移量,产生的图像又会是什么样呢???有兴趣的读者可以尝试一下,我这里就不一一列举了。



暗调滤镜

原理如下:

  • R = R * R / 255
  • G = G * G / 255
  • B = B * b / 255

    完整代码如下:

#include<opencv2/opencv.hpp>#include <iostream>using namespace cv;using namespace std;void anDiaoFilter(Mat &srcImage);int main(){    Mat srcImage = imread("lena.jpg");//图片在工程目录下,否则写绝对路径    if(!srcImage.data || srcImage.empty()){        cout<<"读入图片错误!"<<endl;        return -1;    }    imshow("原图",srcImage);    anDiaoFilter(srcImage);    waitKey(0);    return 0;} void anDiaoFilter(Mat &srcImage){    int rowNum = srcImage.rows;    int colNum = srcImage.cols * srcImage.channels();    for(int j = 0;j<rowNum;j++){        uchar* row = srcImage.ptr<uchar>(j);        for(int i = 0;i<colNum;i++){            row[i] = row[i] * row[i] >>8;        }    }    imshow("暗调滤镜",srcImage);}

效果图如下:

这里写图片描述

0 0
原创粉丝点击