经过的怎样读取图片,我们可以做一些有趣的图像变换,下面我们首先介绍使用遍历的方法实现,然后我们使用内置的函数实现。
矩阵掩码,和卷积神经网络中的卷积类似。一个例子如下:
现在我们看看怎么实现:
- 1 void Sharpen(const Mat& myImage, Mat& Result)
- 2 {
- 3 CV_Assert(myImage.depth() == CV_8U);
- 4
- 5 Result.create(myImage.size(), myImage.type());
- 6 const int nChannels = myImage.channels();
- 7
- 8 for (int j=1; j1; ++j) { // 忽略第一和最后一行,防止数组越界
- 9 const uchar * previous = myImage.ptr(j-1);
- 10 const uchar * current = myImage.ptr(j);
- 11 const uchar * next = myImage.ptr(j+1);
- 12
- 13 uchar * output = Result.ptr(j);
- 14
- 15 // 用连续存储的索引方法,所以每个点有三个uchar值
- 16 // saturate_cast溢出保护
- 17 for (int i=nChannels; i < nChannels * (myImage.cols-1); ++i) {
- 18 *output++ = saturate_cast(5 * current[i]
- 19 - current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);
- 20 }
- 21
- 22 // 四周设置为0
- 23 Result.row(0).setTo(Scalar(0));
- 24 Result.row(Result.rows-1).setTo(Scalar(0));
- 25 Result.col(0).setTo(Scalar(0));
- 26 Result.col(Result.cols-1).setTo(Scalar(0));
- 27 }
- 28 }
我们看看结果:
因为掩码是增强中间,削弱四周,下面如果我们换掩码,使用内置函数看看效果:
- 1 void SharpenUseFilter2D(const Mat& src, Mat& dst) {
- 2 Mat kern = (Mat_<char>(3, 3) << 0,-1,0,
- 3 -1,-1,5,
- 4 0,-1,0);
- 5 filter2D(src, dst, src.depth(), kern);
- 6 }
下面是增强右边元素,减弱左边元素的效果(类似浮雕的效果,大家可以换着掩码来玩):
下面是线性混合操作:
这个可以实现幻灯片的淡入淡出,通过修改 alpha 值。
- 1 resize(src1, src1, cv::Size(200, 200));
- 2 resize(src2, src2, cv::Size(200, 200));
- 3
- 4 namedWindow("123");
- 5
- 6 beta = 1.0 - alpha;
- 7 // dst = alpha * src1 + beta * src2 + gamma
- 8 // 这里gamma设置为0.0
- 9 addWeighted(src1, alpha, src2, beta, 0.0, dst);
下面看看结果:
自己实现的简陋版本,除去错误检查等:
- 1 void addWeight(Mat & src1, double w1, Mat & src2, double w2, Mat & dst) 2 {
- 3 dst.create(src1.size(), src2.type());
- 4 5 Mat_ _src1 = src1;
- 6 Mat_ _src2 = src2;
- 7 Mat_ _dst = dst;
- 8 9
- for (int i = 0; ii) {
- 10
- for (int j = 0; jj) {
- 11
- for (int c = 0; c < 3; ++c) 12 _dst(i, j)[c] = w1 * _src1(i, j)[c] + w2 * _src2(i, j)[c];
- 13
- }
- 14
- }
- 15
- }
- 1 Mat new_image = Mat::zeros(image.size(), image.type());
- 2
- 3 alpha = 1.2; // 1.0-3.0
- 4 beta = 50; // 0-100
- 5
- 6 for (int y=0; yy) {
- 7 for (int x=0; xx) {
- 8 for (int c=0; c<3; ++c)
- 9 // Vec3b = [R, G, B]
- 10 new_image.at(y, x)[c] = saturate_cast
- 11 (alpha * (image.at(y, x)[c]) + beta);
- 12 }
- 13 }
- 14
- 15 Mat new_image_2 = Mat::zeros(image.size(), image.type());
- 16 // -1 代表输入输出类型一样
- 17 image.convertTo(new_image_2, -1, alpha, beta);
结果如下:
可以查阅一下网址
而产生随机数可以使用 RNG rng(0xFFFFFFFF); 这样就可以生成符合一定分布的数,例如高斯分布 rng.uniform(1, 10);
来源: http://www.cnblogs.com/mangoyuan/p/6442885.html