当前位置:网站首页>opencv基本的图像处理
opencv基本的图像处理
2022-08-01 17:33:00 【小小工程员】
基本图像操作
方法 | 描述 | 示例 |
---|---|---|
rect | 设定矩形框 | Rect rect(100, 100, 200, 200); Mat roi = src(rect);//提取src数据中矩形框标定的数据,此时roi指向了src图片对应的矩形数据,是指针! |
cvtColor | 图片类型转换 | cvtColor(src, gray, COLOR_BGR2GRAY); //BGR转灰度图 |
threshold | 二进制阈值化 | threshold(gray, bin, 100, 255, THRESH_BINARY); //大于100全部设为255:白色; 小于100的设为0:黑色; threshold(gray,ibin, 100, 255, THRESH_BINARY_INV);//反二进制阈值化 |
resize | 图片尺寸调整 | resize(src, des1024, Size(1024, 1024), 0, 0, INTER_LINEAR); |
pyrDown | 高斯金字塔,下采样 | pyrDown(src, gsrc);高斯金字塔(Gaussian pyramid):用来向下采样–下采样:图像成倍缩小 |
pyrUp | 拉普拉斯金字塔,上采样 | pyrUp(src, lsrc);//拉普拉斯金字塔(Laplacian pyramid):用来从金字塔低层图像重建上层未采样图像 — 上采样:图像成倍增大 |
addWeighted | 图像混合 | addWeighted(img1, a, img2, 1 - a, 80, dst); // addWeighted:加权; //a:img1的权重,取值范围[0,1]; dst:生成图像 |
rotate | 图像旋转 | cv::rotate(img, rot, ROTATE_90_CLOCKWISE); // cv::rotate cv命名空间下的rotate函数,因此函数太容易被其他库中的函数名冲突。 |
flip | 图像镜像 | cv::flip(img, fl, 1); // type:0(围绕x轴镜像),1(围绕y轴镜像),-1(围绕x和y轴做镜像) |
ROI区域
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
Mat src = imread("1.png");
Rect rect(100, 100, 200, 200);
Mat roi = src(rect); //浅拷贝,只赋值了矩阵头
namedWindow("src");
namedWindow("roi");
moveWindow("roi", 512, 0); //图像显示窗口的位置移动
imshow("src", src);
imshow("roi", roi);
waitKey(0);
return 0;
}
//图像ROI提取 、 放回
Mat binNowX = matFenge(rectBinX).clone(); //获取对应的数据
binNowX.copyTo(BinaryTemplete(rectBinX)); //局部像素复制。原理是将(Mat *)binNowX拷贝到BinaryTemplete的rectBinX区域。
灰度图转换
void RGBToGray(Mat &src, Mat &des)
{
// GRay = (R*30 + G*59 + B*11 +50)/100
des.create(src.rows,src.cols,CV_8UC1);
for (int r = 0; r < src.rows; r++)
{
for (int c = 0; c < src.cols; c++)
{
Vec3b &m = src.at<Vec3b>(r, c); //3位的向量, Vec3b: BGR
int gray = (m[2] * 30 + m[1] * 59 + m[0] * 11 + 50) / 100; //Mat:BGR
des.at<uchar>(r, c) = gray;
}
}
}
int main(int argc, char *argv[])
{
Mat src = imread("1.png");
src.create(3000, 4000, CV_8UC3); //重新创建src内容, imread内容被删除了;为了体现多线程转换的优势,采用了大的图像。
Mat gray;
PrintMs("");
cvtColor(src, gray, COLOR_BGR2GRAY); //采用了多线程,但是第一次由于启动线程等,耗时较久。424ms
PrintMs("cvtColor1");
cvtColor(src, gray, COLOR_BGR2GRAY); //第二次转换则是多线程的优势,转换非常快。17ms
PrintMs("cvtColor2");
Mat mygray;
RGBToGray(src, mygray); //自己转换,单个函数,耗时77ms
PrintMs("RGBToGray");
namedWindow("src");
namedWindow("gray");
namedWindow("mygray");
imshow("src", src);
imshow("gray", gray);
imshow("mygray", mygray);
waitKey(0);
return 0;
}
图像增益设计
//
///@para a float 对比度 1.0~3.0
///@para b int 亮度 0~100
void ChangeGain(Mat &src, Mat &des, float a, int b)
{
//g(r,c) = a*f(r,c) + b
des.create(src.rows, src.cols, src.type());
for (int r = 0; r < src.rows; r++)
{
for (int c = 0; c < src.cols; c++)
{
for (int i = 0; i < 3; i++)
{
des.at<Vec3b>(r, c)[i] = saturate_cast<uchar>(a * src.at<Vec3b>(r, c)[i] + b); //saturate_cast<uchar>:防止溢出;超过uchar的值255就设定为255
}
}
}
}
int main(int argc, char *argv[])
{
//调整对比度和亮度 ; gain:增益
Mat src = imread("2.jpg");
Mat des;
PrintMs("");
ChangeGain(src,des, 2.0,50); //对比度:2.0; 亮度:+50;
PrintMs("ChangeGain");
Mat des2;
src.convertTo(des2, -1, 2.0, 50); //opencv提供的函数,-1:负数代表与原图的类型一致; 性能比自己写的 函数性能高。
PrintMs("convertTo");
namedWindow("src");
namedWindow("des");
namedWindow("des2");
imshow("src", src);
imshow("des", des);
imshow("des2", des2);
waitKey(0);
return 0;
}
图像尺寸调整
void xresize(Mat &src, Mat &des, Size size) // Size:是cv命名空间的Size,很容易冲突的类型。
{
des.create(size, src.type());
//映射的原图坐标
int sx, sy = 0;
float fx = (float)src.cols / des.cols; // 原图列数(宽度)/目标图列数
float fy = (float)src.rows / des.rows; // 原图的行数(高度)/目标图的行数
for (int x = 0; x < des.cols; x++)
{
sx = fx * x + 0.5; // int类型,四舍五入
for (int y = 0; y <des.rows; y++)
{
sy = fy * y + 0.5;
des.at<Vec3b>(y, x) = src.at<Vec3b>(sy, sx); // 目标坐标的内容值等于原图相应坐标的内容值
}
}
}
int main(int argc, char *argv[])
{
//图像尺寸调整算法,手动实现近邻算法;放大/缩小
Mat src = imread("1.png"); //512*512 256 1024
Mat img256,img1024,des256,des1024;
resize(src, des256, Size(256, 256), 0, 0, INTER_NEAREST);
PrintMs();
//xresize(src, img256, Size(256, 256));
//PrintMs("img256");
xresize(src, img1024, Size(1024, 1024));
//resize(src, img1024, Size(4024, 4024), 0, 0, INTER_NEAREST);
PrintMs("img1024");
//resize(src, des256, Size(1024, 1024), 0, 0, INTER_NEAREST); // 近邻算法:INTER_NEAREST , 简单的临近值拷贝:放大时边角处容易出现马赛克。原来一个像素点复制成了一个大的范围像素;缩小的话会有内容损失。
resize(src, des1024, Size(1024, 1024), 0, 0, INTER_LINEAR); //双线性内插值算法(缺省使用的算法),不是简单的拷贝,而是做了临近的运算;输出像素是输入邻域像素的加权和。
//源图像位置在它附近的2*2区域4个临近像素的值通过加权平均计算得出的。低通滤波性质,使高频分量受损,图像轮廓可能会模糊一点。
PrintMs("des1024");
namedWindow("src");
//namedWindow("img256");
namedWindow("des1024");
namedWindow("img1024");
imshow("src", src);
imshow("img1024", img1024);
imshow("des1024", des1024);
moveWindow("des1024", 512, 0); //图像显示窗口的位置移动
//imshow("img1024", img1024);
waitKey(0);
return 0;
}
图像混合,设定透明度
int main(int argc, char *argv[])
{
Mat img1 = imread("1.png");
Mat img2 = imread("2.png");
resize(img2, img2, img1.size()); //!!!图像大小必须一样;
Mat dst;
float a = 0.8;
addWeighted(img1, a, img2, 1 - a, 80, dst); // addWeighted:加权; //a:img1的权重,取值范围[0,1]; dst:生成图像
namedWindow("blending");
imshow("blending", dst);
waitKey(0);
return 0;
}
图像合并,并列显示
/************************************************************************ 注意: Mat r1 = des(Rect(0, 0, width1, height)); //1号图,!!!: des(Rect())这个并不会新创建Mat r1数据,而是将r1这个指针对象指向des这个图,对des进行直接改变。 **********************************************************************/
#include <opencv2/imgproc.hpp>
int main(int argc, char *argv[])
{
Mat img1 = imread("1.png");
Mat img2 = imread("2.png");
int height = img1.rows; //设定两幅图像高度统一, 宽度不统一
int width1 = img1.cols;
int width2 = img2.cols;
// 将高度较高的图像等比缩放与低图像的高度一致
if (img1.rows > img2.rows)
{
height = img2.rows;
width1 = img1.cols * ((float)img2.rows / (float)img1.rows); //等比缩放,高度一致,宽度等比例改变。
resize(img1, img1, Size(width1, height));
}
else if(img1.rows < img2.rows)
{
width2 = img2.cols * ((float)img1.rows / (float)img2.rows);
resize(img2, img2, Size(width2, height));
}
//创建目标Mat
Mat des;
des.create(height, width1 + width2, img1.type()); //创建, 谨记!!!该复用函数,此时参数第一个是高,第二个是宽
Mat r1 = des(Rect(0, 0, width1, height)); //1号图,!!!: des(Rect())这个并不会新创建Mat r1数据,而是将r1这个指针对象指向des这个图,对des进行直接改变。
img1.copyTo(r1); // 将img1拷贝到r1区域,r1区域指针指向des,故而最终拷贝到了des定义的数据变量中。
Mat r2 = des(Rect(width1, 0, width2, height));
img2.copyTo(r2);
namedWindow("des");
imshow("des", des);
waitKey(0);
destroyAllWindows();
return 0;
}
边栏推荐
猜你喜欢
JumpServer堡垒机部署
zabbix部署和简单使用
Xingtu has been short of disruptive products?Will this M38T from the Qingdao factory be a breakthrough?
ROS2系列知识(5):【参数】如何管理?
广汽埃安“弹匣电池”,四大核心技术,出行安全保障
The site is not found after the website is filed. You have not bound this domain name or IP to the corresponding site! The configuration file does not take effect!
Bugku-Misc-贝斯手
统信软件、龙芯中科等四家企业共同发布《数字办公安全创新方案》
今年最火爆的词:商业分析,看这一篇就够了!
SRM供应商管理系统如何助力口腔护理企业实现采购战略的转型升级
随机推荐
深圳市商务局2022年度中央资金(跨境电子商务企业市场开拓扶持事项)申报指南
生物制药产业发展现状和趋势展望
LeetCode第 303 场周赛
2022强网杯CTF---强网先锋 ASR wp
Winform message prompt box helper class
The site is not found after the website is filed. You have not bound this domain name or IP to the corresponding site! The configuration file does not take effect!
C#的DateTime帮助类
GridControl helper class for DevExpress
【100个网络运维工作者必须知道的小知识!】
金仓数据库 KDTS 迁移工具使用指南(2. 简介)
酷逼了 Pathetic Dog 第 304 场周赛
半自动化爬虫-爬取一个网站的内容及回复
主流小程序框架性能分析
C#的路径帮助类
广汽埃安“弹匣电池”,四大核心技术,出行安全保障
C# CSV format file helper class
插入排序 优化插入排序
The anxiety of the post-90s was cured by the vegetable market
ROS2系列知识(6):Action服务概念
程序员架构修炼之道:如何设计“易理解”的系统架构?