当前位置:网站首页>Basic image processing in opencv
Basic image processing in opencv
2022-08-01 17:34:00 【little engineer】
基本图像操作
| 方法 | 描述 | 示例 |
|---|---|---|
| rect | Set the rectangle frame | Rect rect(100, 100, 200, 200); Mat roi = src(rect);//提取srcThe data marked by the rectangle in the data,此时roi指向了srcThe rectangle data corresponding to the picture,是指针! |
| 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):用来向下采样–下采样:The image is scaled down exponentially |
| pyrUp | 拉普拉斯金字塔,上采样 | pyrUp(src, lsrc);//拉普拉斯金字塔(Laplacian pyramid):用来从金字塔低层图像重建上层未采样图像 — 上采样:The image is multiplied |
| 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函数,So functions are too easily conflicted by function names in other libraries. |
| 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); //浅拷贝,Only the matrix header is assigned
namedWindow("src");
namedWindow("roi");
moveWindow("roi", 512, 0); //The position of the image display window is moved
imshow("src", src);
imshow("roi", roi);
waitKey(0);
return 0;
}
//图像ROI提取 、 放回
Mat binNowX = matFenge(rectBinX).clone(); //获取对应的数据
binNowX.copyTo(BinaryTemplete(rectBinX)); //Local pixel copy.原理是将(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内容被删除了;In order to reflect the advantages of multi-threaded conversion,A large image is used.
Mat gray;
PrintMs("");
cvtColor(src, gray, COLOR_BGR2GRAY); //采用了多线程,But the first time due to starting threads etc,耗时较久.424ms
PrintMs("cvtColor1");
cvtColor(src, gray, COLOR_BGR2GRAY); //The second conversion is the advantage of multithreading,Conversion is very fast.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;
}
Image gain design
//
///@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:Negative numbers represent the same type as the original image; Performance is better than writing it yourself Function performance is high.
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,Types that are prone to conflict.
{
des.create(size, src.type());
//The original image coordinates of the map
int sx, sy = 0;
float fx = (float)src.cols / des.cols; // Original image columns(宽度)/The number of target graph columns
float fy = (float)src.rows / des.rows; // The number of lines in the original image(高度)/The number of rows in the target graph
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); // The content value of the target coordinate is equal to the content value of the corresponding coordinate of the original image
}
}
}
int main(int argc, char *argv[])
{
//Image resizing algorithm,Implement the nearest neighbor algorithm manually;放大/缩小
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 , Simple copy of adjacent value:Mosaics are prone to appear in the corners when zoomed in.The original one pixel is copied into a large range of pixels;There will be a loss of content if you shrink it.
resize(src, des1024, Size(1024, 1024), 0, 0, INTER_LINEAR); //Bilinear interpolation algorithm(The algorithm used by default),不是简单的拷贝,Instead, it does an adjacent operation;The output pixel is a weighted sum of the input neighborhood pixels.
//The source image position is near it2*2区域4The values of adjacent pixels are calculated by weighted average.Low-pass filtering properties,使高频分量受损,Image outlines may be blurred a bit.
PrintMs("des1024");
namedWindow("src");
//namedWindow("img256");
namedWindow("des1024");
namedWindow("img1024");
imshow("src", src);
imshow("img1024", img1024);
imshow("des1024", des1024);
moveWindow("des1024", 512, 0); //The position of the image display window is moved
//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()); //!!!The images must be the same 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())This is not newly createdMat r1数据,而是将r1This pointer object points todes这个图,对desmake direct changes. **********************************************************************/
#include <opencv2/imgproc.hpp>
int main(int argc, char *argv[])
{
Mat img1 = imread("1.png");
Mat img2 = imread("2.png");
int height = img1.rows; //Set the height of the two images to be uniform, The width is not uniform
int width1 = img1.cols;
int width2 = img2.cols;
// Scale taller images to match the height of lower images
if (img1.rows > img2.rows)
{
height = img2.rows;
width1 = img1.cols * ((float)img2.rows / (float)img1.rows); //等比缩放,高度一致,The width is proportionally changed.
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()); //创建, 谨记!!!The multiplexing function,At this point the first parameter is high,第二个是宽
Mat r1 = des(Rect(0, 0, width1, height)); //1号图,!!!: des(Rect())This is not newly createdMat r1数据,而是将r1This pointer object points todes这个图,对desmake direct changes.
img1.copyTo(r1); // 将img1拷贝到r1区域,r1The area pointer points todes,So it was finally copieddesin the defined data variable.
Mat r2 = des(Rect(width1, 0, width2, height));
img2.copyTo(r2);
namedWindow("des");
imshow("des", des);
waitKey(0);
destroyAllWindows();
return 0;
}
边栏推荐
- 吴恩达机器学习课后习题——kmeans
- 2022 Strong Net Cup CTF---Strong Net Pioneer ASR wp
- 数字化采购管理系统开发:精细化采购业务流程管理,赋能企业实现“阳光采购”
- 开发工具:第五章:使用idea生成实体类
- Vulnhub target drone: HARRYPOTTER_ NAGINI
- MySQL's maximum recommended number of rows is 2000w, is it reliable?
- 后台管理系统的权限思路
- LeetCode第 303 场周赛
- The anxiety of the post-90s was cured by the vegetable market
- SQL函数 TO_CHAR(三)
猜你喜欢

Ali's official Redis development specification

不需要写代码,快速批量修改文件夹中图片的格式

Description of common operations and help projects about DevExpress in C#

成为优秀架构师必备技能:怎样才能画出让所有人赞不绝口的系统架构图?秘诀是什么?快来打开这篇文章看看吧!...

GRUB2的零日漏洞补丁现已推出

C# LibUsbDotNet 在USB-CDC设备的上位机应用

SRM供应商管理系统如何助力口腔护理企业实现采购战略的转型升级

酷逼了 Pathetic Dog 第 304 场周赛

SQL的索引详细介绍

Topology零部件拆解3D可视化解决方案
随机推荐
2022年SQL大厂高频实战面试题(详细解析)
完美指南|如何使用 ODBC 进行无代理 Oracle 数据库监控?
访问域名直接访问wordpress
自定义注解实现日志打印时屏蔽特定字段不打印
2022年MySQL最新面试题
【100个网络运维工作者必须知道的小知识!】
08 Spark cluster construction
实现mnist手写数字识别
Detailed explanation of the working principle of crystal oscillator
频域分析实践介绍
opencv基本的图像处理
Financial products with high annualized returns
TCP百万并发服务器优化调参
gtk显示4通道rgba图像
Bugku-Misc-贝斯手
TCP million concurrent server optimization parameters
中信证券是国内十大券商吗?怎么开户安全?
酷逼了 Pathetic Dog 第 304 场周赛
Complete knapsack problem to find the number of combinations and permutations
MySql 怎么查出符合条件的最新的数据行?