Opencv2系列学习笔记2(图像的其它操作)
本节主要涉及到图像的领域、算术操作以及如何操作图像感兴趣的区域。
一:邻域操作
以下例子主要对图像进行锐化。基于拉普拉斯算子<后面讨论>。这幅图像的边缘部分将得到放大,细节部分将更加的锐利。计算方式为:
sharpened_pixel = 5*current – left – right –up – down.
Code:
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\core\core.hpp>
#include <iostream> using namespace std;
using namespace cv; void sharpen(const Mat &image, Mat &result)
{
const int nChannels = image.channels();
for(int j = 1; j < image.rows - 1; j++)
{
const uchar *previous = image.ptr<const uchar>(j-1); // 上一行
const uchar *current = image.ptr<const uchar>(j); // 此行
const uchar *next = image.ptr<const uchar>(j+1); //下一行
uchar *output = result.ptr<uchar>(j); for(int i = 1; i < image.cols - 1; i++)
{
if(image.channels() == 1) // 黑白图像
{
output[i] = saturate_cast<uchar>(5*current[i] - current[i-1] - current[i+1] - previous[i] - next[i]);
}
else if(image.channels() == 3) // 彩色图像
{
*(output + i*image.elemSize()) =saturate_cast<uchar>(5 * *(current + i*image.elemSize()) - *(current + (i-1)*image.elemSize())- *(current + (i+1)*image.elemSize()) - *(previous + i*image.elemSize())- *(next + i*image.elemSize()));
*(output + i*image.elemSize() + 1) = saturate_cast<uchar>(5 * *(current + i*image.elemSize() + 1) - *(current + (i-1)*image.elemSize() + 1)- *(current + (i+1)*image.elemSize() + 1) - *(previous + i*image.elemSize() + 1)- *(next + i*image.elemSize() + 1));
*(output + i*image.elemSize() + 2) = saturate_cast<uchar>(5 * *(current + i*image.elemSize() + 2) - *(current + (i-1)*image.elemSize() + 2)- *(current + (i+1)*image.elemSize() + 2) - *(previous + i*image.elemSize() + 2)- *(next + i*image.elemSize() + 2));
} }
/*for(int i = nChannels; i < nChannels * (image.cols - 1); ++i)
{
*output ++ = saturate_cast<uchar>(5*current[i] - current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]); }*/
}
result.row(0).setTo(Scalar(0));
result.row(result.rows - 1).setTo(Scalar(0));
result.col(0).setTo(Scalar(0,0,0));
result.col(result.cols - 1).setTo(Scalar(0));
return;
} void sharpen2D(const Mat &image, Mat &result)
{
Mat kernel(3, 3, CV_32FC1, Scalar(0));
kernel.at<float>(1,1) = 5.0;
kernel.at<float>(0, 1) = -1.0;
kernel.at<float>(1, 0) = -1.0;
kernel.at<float>(1, 2) = -1.0;
kernel.at<float>(2,1) = -1.0;
/*也可以这样定义,这是opencv中简单初始化只有几个像素的mat类型*/
//Mat kernel = (Mat_<float>(3,3) << 0, -1.0, 0.0, -1.0, 5.0, -1.0, 0, -1.0, 0);
filter2D(image, result,image.depth(), kernel);
return;
}
int main()
{
Mat image = imread("F:\\huangrong.jpg", 0);
Mat result;
cout << image.depth() << endl;
result.create(Size(image.cols, image.rows), image.type());
sharpen(image, result);
//sharpen2D(image, result);
namedWindow("image");
imshow("image", image);
namedWindow("result");
imshow("result", result);
waitKey(0);
return 0;
}
Explaination:
(1) saturate_cast<uchar>主要是类型检查来保证转换的安全性。如对于计算得到的结果不在0~255范围内,则进行截断。通常做法是将负值截断为0,将大于255的截断为255.
(2) Matkernel = (Mat_<float>(3,3) << 0, -1.0, 0.0, -1.0, 5.0, -1.0, 0,-1.0, 0);
//opencv中简单初始化只有几个像素的mat类型
(3) result.row(0).setTo(Scalar(0));
//可以将矩阵的第0行所有像素全部设置为0
(4)opencv中自带了filter2D这个函数可以进行领域操作,其结果是一样的,在某些情况下回更高效点。
Result:
二:算术操作
Code:
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream> using namespace std;
using namespace cv; Mat addWeight(Mat &image, Mat &image2)
{
Mat result;
//addWeighted(image, 0.5, image2, 0.5, 0.0, result);
result = image*0.5 + image2*0.5 + 0.3; // 大多数算术函数在opencv2中都有对应的重载操作符
return result;
} Mat addWeight2(Mat &image, Mat &image3)
{
Mat result;
vector<Mat> planes;
split(image, planes); /// 将一个彩色三通道图像分解为三个单通道图像
planes[0] += image3;
merge(planes, result); /// 将三个单通道图像合并为一个彩色三通道图像
return result;
} int main()
{
Mat image = imread("F:\\huangrong.jpg", 1);
if(!image.data){
cout << "fail to load image" << endl;
return 0;
}
Mat image2 =Mat::zeros(image.rows, image.cols, image.type());
//Mat image2(image.rows, image.cols, image.type(), Scalar(255, 255, 255));
Mat result;
result = addWeight(image, image2); Mat result2;
Mat image3 = Mat::zeros(image.rows, image.cols, CV_8UC1);
result2 = addWeight2(image, image3);
namedWindow("image");
imshow("image", image);
namedWindow("image2");
imshow("image2", image2);
namedWindow("result");
imshow("result", result);
namedWindow("result2");
imshow("result2", result2);
waitKey(0);
return 0;
}
Explaination:
(1) 以上实现的是两幅图像相加,即可用opencv自带的函数addWeighted,也可用重载的运算符+。其它如&,|,^,~等都被重载了。除了加法,还有其它运算,如矩阵求逆m1.inv(),装置m1.t(),矩阵行列式m1.determinant()等
(2) split(image, planes);和merger(planes,image); 分别是将一个彩色三通道图像分解为三个单通道图像和将三个单通道图像合并为一个彩色三通道图像
Result:
三:定义感兴趣区域
Code:
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream> using namespace std;
using namespace cv; int main()
{
Mat image = imread("F:\\huangrong.jpg", 1);
if(!image.data){
cout << "fail to load image" << endl;
return 0;
}
Mat tongtong = imread("F:\\tt.png", 1);
//Mat imageROI = image(Rect(140,20,tongtong.cols, tongtong.rows));
//Mat imageROI(image, Rect(140,20,tongtong.cols, tongtong.rows));//第二种方式
Mat imageROI = image(Range(20, 20 + tongtong.rows),Range(140, 140+tongtong.cols)); // 第三种方式
tongtong.copyTo(imageROI);
namedWindow("imageROI");
imshow("imageROI", imageROI);
namedWindow("image");
imshow("image",image);
waitKey(0);
return 0;
}
Explaination:
(1) 三种方式:
a) MatimageROI = image(Rect(140,20,tongtong.cols, tongtong.rows));
b) MatimageROI(image, Rect(140,20,tongtong.cols, tongtong.rows));
c) MatimageROI = image(Range(20, 20 + tongtong.rows),Range(140, 140+tongtong.cols)); // 其中Range是指从起始索引到终止索引(不包含终止索引)的一段连续序列。
(2)其中需要注意的是:ROI和原始图像共享数据缓冲区,对ROI的任何变换都会影响到图像对应的区域。
作者:小村长 出处:http://blog.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)
Opencv2系列学习笔记2(图像的其它操作)的更多相关文章
- Opencv2系列学习笔记8(图像滤波)
一:概念: 滤波是信号处理机图像处理中的一个基本操作.滤波去除图像中的噪声,提取感兴趣的特征,允许图像重采样. 图像中的频域和空域:空间域指用图像的灰度值来描述一幅图像:而频域指用图像灰度值的变化来描 ...
- opencv学习笔记(五)----图像的形态学操作
图像的形态学操作有基本的腐蚀和膨胀操作和其余扩展形态学变换操作(高级操作)-----开运算,闭运算,礼帽(顶帽)操作,黑帽操作...(主要也是为了去噪声,改善图像) 形态学操作都是用于处理二值图像(其 ...
- Opencv2系列学习笔记10(提取连通区域轮廓)
连通区域指的是二值图像中相连像素组成的形状.而内.外轮廓的概念及opencv1中如何提取二值图像的轮廓见我的这篇博客:http://blog.csdn.net/lu597203933/article/ ...
- Opencv2系列学习笔记10(提取连通区域轮廓) 另一个
http://blog.csdn.net/lu597203933/article/details/17362457 连通区域指的是二值图像中相连像素组成的形状.而内.外轮廓的概念及opencv1中如何 ...
- OpenCV2计算机编程手册(一)操作像素
1. 引言 从根本上来说,一张图像是一个由数值组成的矩阵.这也是opencv中使用 代表黑色,代表白色.对于彩色图像(BGR三通道)而言,每个像素需要三个这样的8位无符号数来表示,这种情况下,矩阵的元 ...
- MVA Universal Windows Apps系列学习笔记1
昨天晚上看了微软的Build 2015大会第一天第一场演讲,时间还挺长,足足3个小时,不过也挺震撼的.里面提到了windows 10.Microsoft edge浏览器.Azure云平台.Office ...
- opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测
opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测 这章讲了 sobel算子 scharr算子 Laplacion拉普拉斯算子 图像深度问题 Canny检测 图像梯度 sobel算子 ...
- Caffe学习笔记4图像特征进行可视化
Caffe学习笔记4图像特征进行可视化 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit201 ...
- OpenCV2:第六章 图像几何变换
一.简介 图像的几何变换有距离变换 坐标映射 平移 镜像 旋转 缩放 仿射变换等 二.重映射 把一张图像重新排列像素,比如倒置 CV_EXPORTS_W void remap( InputArr ...
随机推荐
- [LeetCode]题解(python):097-Interleaving String
题目来源: https://leetcode.com/problems/interleaving-string/ 题意分析: 给定字符串s1,s2,s3,判断s3是否由s1和s2穿插组成.如“abc” ...
- 我的Fedora环境
Fedora现在也更新到了第20个版本,只是在15+以后的版本,大多数操作,都是大同小异的,也不必特意去关注版本号,只有对应到具体的软件,可能会因为库的版本,有或多或少的区别. 之前每次都喜欢按照一些 ...
- activemq在windows下启动报错,闪退问题
查验了网上各种方法,都没搞定,最后楼主决定按照linux的解决套路来,把windows计算机名称改为纯英文字母,原计算机名:lee_pc,修改后为leepc,然后重启电脑,再重新运行activemq. ...
- WEB和APP谁是互联网未来
据中国多家权威报告显示,作为多年专业化互联网公司炎帝网络科技综合评估预测,预计2016年全球互联网设备将达到100亿部.如果届时全球人口达到73亿,意味着平均每人将有1.4部设备.智能交通将增长50倍 ...
- 网站流量统计系统 phpMyVisites
phpMyVisites是一个网站流量统计系统,它能够提供非常详细的统计报告和高级图形报表.phpMyVisites不是一个Apache log分析工具,它建有自己的log.它的特点包括: 安装部署: ...
- 在js中获取query string 以及重写URL的函数
函数用途:如标题.1. 从URL中解析出參数,2.重写URL中的參数值 例如以下代码所看到的.包括了測试.能够直接copy到浏览器中,输入測试地址:localhost:xxx?a=1&b=2& ...
- 【剑指offer】调整数组顺序
转载请注明出处:http://blog.csdn.net/ns_code/article/details/25829395 剑指offer上的第14题,九度OJ为了确保输出的结果的唯一性,在输出上做了 ...
- (" use strict")Javascript 严格模式详解
Javascript 严格模式详解 转载别人的博客内容,浏览了一遍,没有全部吸收,先保存一下链接 http://www.ruanyifeng.com/blog/2013/01/javascript_s ...
- qnx:从API开始理解QNX -- 消息传递
从API开始理解QNX -- 消息传递 http://www.openqnx.com/chinese/viewtopic.php?f=5&t=2161 1. 频道与连接 Chann ...
- iOS推送介绍
iOS消息推送的工作机制可以简单的用下图来概括: Provider是指某个iPhone软件的Push服务器,APNS是Apple Push Notification Service的缩写,是苹果的服务 ...