opencv实战2-修改保存图片、像素操作

1 加载修改保存图像

1.1 修改图像

opencv中 灰度图像由常量 CV_8U 表示 C++ 中的 unsigned char;

 三通道图像由 常量 CV_8UC3 表示;

 1.2 保存图像

#include<stdio.h>
#include <cstdio>  
#include <iostream>
#include <opencv2/opencv.hpp>
#include  <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
int main() 
{
	Mat image;
	image = cv::imread("F:/project/OPENCV_TEST_PROJECT/picture/test.jpg");
	if (image.empty()) {
		cout << "error";
		return 0;
	}
	cv::namedWindow("Original Image");
	cv::imshow("Original Image",image);
	Mat result;
	cv::flip(image,result,1);//反转图片 正数表示水平 ;0 表示垂直;负数表示水平和垂直
	cv::namedWindow("Flip Image");
	cv::imshow("Flip Image", result);
	cv::imwrite("F:/project/OPENCV_TEST_PROJECT/picture/flip.jpg", result);//保存结果
	cv::waitKey(0);//0 表示等待按键
}

1.3 在图片上绘制形状或添加文字

#include<stdio.h>
#include <cstdio>  
#include <iostream>
#include <opencv2/opencv.hpp>
#include  <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
int main() 
{
	Mat image;
	image = cv::imread("F:/project/OPENCV_TEST_PROJECT/picture/test.jpg");
	if (image.empty()) {
		cout << "error";
		return 0;
	}
	cv::namedWindow("Original Image");
	cv::imshow("Original Image",image);
	cv::circle(image, cv::Point(155, 110), //中心点坐标
		55, //半径
		0,  //颜色
		3);//厚度
	cv::namedWindow("Result Image");
	cv::imshow("Result Image", image);

	cv::waitKey(0);//0 表示等待按键
}

 可使用 cv::putText 函数在图片上添加文字。

1.4 定义感兴趣区域ROI

#include<stdio.h>
#include <cstdio>  
#include <iostream>
#include <opencv2/opencv.hpp>
#include  <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
int main() 
{
	Mat image;
	image = cv::imread("F:/project/OPENCV_TEST_PROJECT/picture/test.jpg");
	if (image.empty()) {
		cout << "error";
		return 0;
	}
	//创建一个240*330 红色图像 通道是bgr
	Mat image2(500,330,CV_8UC3,cv::Scalar(0,0,255));
	//在图像的右下角定义一个感兴趣区域
	Mat imageROI(image,
		cv::Rect(image.cols - image2.cols,  //ROI坐标
				image.rows - image2.rows,
				image2.cols, image2.rows));  //ROI 大小
	//插入
	image2.copyTo(imageROI);
	cv::namedWindow("Original Image");
    cv::imshow("Original Image", image);
 
	cv::waitKey(0);//0 表示等待按键
}

显示效果如下所示,原图上增加 红色矩阵:

2 像素操作

2.1 使用指针的方式操作图像

获取一行像素值的字节数

int nc = image.cols * images.channels();

 返回一行元素的起始地址

uchar * data = image.ptr<uchar>(j);//j为第j行的地址

 操作像素的字节

*data = *data/8;

 对原图像进行拷贝

cv::Mat iamgeClone = image.clone();//图像的深拷贝

使用迭代器遍历图像元素

cv::Mat<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();
cv::Mat<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();
for(;it!=itend;++it)
{
    (*it)[0] = 112;//[]中访问元素通道
    (*it)[1] = 255;//[]中访问元素通道
    (*it)[2] = 255;//[]中访问元素通道
}

2.2 访问图像元素

生成椒盐噪声:

#include<stdio.h>
#include <cstdio>  
#include <iostream>
#include <opencv2/opencv.hpp>
#include  <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#include <random>
void salt(cv::Mat image, int n) { //待处理如下,生成的椒盐噪声数量
	std::random_device seed_device;
	std::default_random_engine engine(seed_device());//通过operator()取得设备产生的随机值
	std::uniform_int_distribution<int> distrRow(0, image.rows -1);//10到100,int类型,线性分布
	std::uniform_int_distribution<int> distrCols(0, image.cols - 1);//10到100,int类型,线性分布
	int i, j;
	for (int k = 0; k < n; k++) {
		i = distrRow(engine);
		j = distrCols(engine);
		if (image.type() == CV_8UC1) {  //灰度图
			image.at<uchar>(i, j) = 255;
		}
		else if (image.type() == CV_8UC3) {  //灰度图
			image.at<cv::Vec3b>(i, j)[0] = 255;
			image.at<cv::Vec3b>(i, j)[1] = 255;
			image.at<cv::Vec3b>(i, j)[2] = 255;
		}
	}
	
	engine.seed(); //将引擎设为初始化状态
	cv::namedWindow("Original Image");
	cv::imshow("Original Image", image);
}

使用Mat.at方法访问元素,at方法被实现成一个模板方法,调用时必须指定图像元素的类型。

image.at<cv::Vec3b>(i, j)[0] = 255;

2.3 计算某段代码运行的时间

const int64 start = cv::getTickCount();//获取计算机开机到当前的时钟周期数
//运行一段代码
double duration = (cv::getTickCount()-start)/cv::getTickFrequency();//换算为以秒为单位

2.4 扫描图像并访问相邻元素

滤波函数 cv::filter2D,定义内核kernel

void sharpen2D(const cv::Mat &image,cv::Mat &result)
{
    cv::Mat kernel(3,3,CV_32F,cv::Scalar(0));//构造内核,所有入口初始化为0
    //对内核赋值
    kernel.at<float>(1,1)=5.0;
    kernel.at<float>(0,1)=-1.0;
    kernel.at<float>(2,1)=-1.0;
    kernel.at<float>(1,0)=-1.0;
    kernel.at<float>(1,2)=-1.0;

    //对图像滤波操作
    cv::filter2D(image,result,image.depth(),kernel);
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值