1、颜色处理

1.1、颜色模型转换

基本知识:有5种颜色模型,第一种是最常见的RGB模型,就是我们通常使用的红绿蓝三色素,同过不同比例的混合显现出不同色彩。第二种YUV颜色模型,一般是电视信号系统采取的颜色编码,Y表示像素亮度,U表示红色与亮度信号差值,V表示蓝色与亮度差值。第三种是HSV颜色模型,H是色度,S是饱和度,V是亮度。第四种是Lab颜色模型,L表示亮度,a和b是两个颜色通道,取值范围是-128到127,其中a通道由小到大颜色从绿变红,b通道有小到大颜色从蓝变黄。第五种是GRAY颜色模型。GRAY模型就是我们常说的灰度图像模型。取值范围0到255,颜色从黑变白。
在opencv中,颜色模型的转换很简单,通过cvtColor函数就能实现颜色模型转换。

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {/*颜色模型转换*///声明Mat yuv_i, hsv_i, lab_i, gray_i;//读取图片Mat im = imread("E:\\opencv_study\\opencv_study.png");//颜色模型转换cvtColor(im, yuv_i,COLOR_RGB2YUV);cvtColor(im, hsv_i, COLOR_RGB2HSV);cvtColor(im, lab_i, COLOR_RGB2Lab);cvtColor(im, gray_i, COLOR_RGB2GRAY);//显示图片imshow("原图", im);imshow("yuv", yuv_i);imshow("hsv", hsv_i);imshow("lab", lab_i);imshow("gray", gray_i);waitKey(0);destroyAllWindows();return 0;
}

运行代码

1.2 多通道分离与合并

在opencv中,通过split函数分离多通道,通过merge函数合并多通道。
split(in,out);in是指待分离多通道图像,out是数组或者容器的mat类。
merge同理,与split不同的是,merge用数组时候需要通道数作为参数,如merge(in,3,out).而容器不用。

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {/*多通道分离与合并*///图像读取Mat im = imread("E:\\opencv_study\\opencv_study.png");//多通道分离vector<Mat> images;Mat im0,im1,im2;split(im, images);im0 = images.at(0);im1 = images.at(1);im2 = images.at(2);imshow("R通道", im0);imshow("G通道", im1);imshow("B通道", im2);//多通道合并cout << "图片大小:" << images[1].size() << endl;images[1] = Mat::zeros(images[1].size(), CV_8UC1);Mat result;merge(images,result);imshow("缺少G通道", result);waitKey(0);destroyAllWindows();return 0;
}

运行得:

2、像素处理

2.1、像素统计

最大值与最小值:minMaxLoc(im, &minv, &maxv, &minid, &maxid);
im为单通道矩阵。minv,maxv分别为通道的最大值与最小值。minid与maxid分别为矩阵中的位置,为point类型。
平均值与标准差计算:meanStdDev(im,my_mean,my_std);
im为图像,my_mean是平均值,my_std为标准差;

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {Mat im = imread("E:\\opencv_study\\opencv_study.png");vector<Mat> images;Mat im0, im1, im2;split(im, images);im0 = images.at(0);im1 = images.at(1);im2 = images.at(2);double minv, maxv;Point minid, maxid;minMaxLoc(im0, &minv, &maxv, &minid, &maxid);cout << "最大值:" << maxv << "---位置:" << maxid << endl;cout << "最小值:" << minv << "---位置:" << minid << endl;Mat my_mean,my_std;meanStdDev(im,my_mean,my_std);cout << "平均值:" << my_mean << "---标准差:" << my_std<<endl;return 0;
}

运行得:

2.2、图像与图像间操作

两图像对应较小像素得到的图像:min(im1,im2,min_im),min_im是得到的图像。
两图像对应较大像素得到的图像:min(im1,im2,max_im),max_im是得到的图像。

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {//读取图片Mat im = imread("E:\\opencv_study\\opencv_study.png");//得到图片长宽int w=im.size().width;int h = im.size().height;//裁剪成两幅一样大的图片Mat im1, im2;Rect rect1(0, 0, w / 2, h);Rect rect2(w/2, 0, w / 2, h);im1 = im(rect1);im2 = im(rect2);//比较对应像素大小获得对应像素Mat min_im,max_im;min(im1, im2, min_im);max(im1, im2, max_im);imshow("min", min_im);imshow("max", max_im);waitKey(0);destroyAllWindows();
}

运行得:

两幅图像的逻辑操作:
进行的逻辑运算是从十进制转换成二进制进行。

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {/*图像逻辑运算*/Mat im = imread("E:\\opencv_study\\opencv_study.png");Mat my_or, my_and, my_xor, my_not;bitwise_and(im, im, my_and);bitwise_or(im, im, my_or);bitwise_xor(im, im, my_xor);bitwise_not(im, my_not);imshow("and", my_and);imshow("or", my_or);imshow("xor", my_xor);imshow("not", my_not);waitKey(0);destroyAllWindows();
}

2.3、图像二值化

原理:比较简单,通过设置阈值得到二值图像。

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {Mat im = imread("E:\\opencv_study\\opencv_study.png");Mat im_b, im_bv;threshold(im, im_b, 125, 255, THRESH_BINARY);threshold(im, im_bv, 125, 255, THRESH_BINARY_INV);imshow("im_b", im_b);imshow("im_bv", im_bv);waitKey(0);destroyAllWindows();return 0;
}

3、图像变换

3.1、图像连接

图像连接就是降两张具有相同高度或者相同宽度的图像连接起来。
opencv4中提供了两个函数用于图像连接,vconcat()函数用于实现图像的上下连接,hconcat()函数用于实现图像的左右连接。

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {//读取图片Mat im = imread("E:\\opencv_study\\opencv_study.png");//把一张图片分成两份int w = im.size().width;int h = im.size().height;Mat im1, im2;Rect rect1(0, 0, w / 2, h);Rect rect2(w / 2, 0, w / 2, h);im1 = im(rect1);im2 = im(rect2);//图片连接Mat im_v, im_h;vconcat(im1, im2, im_v);hconcat(im1, im2, im_h);imshow("上下连接", im_v);imshow("左右连接", im_h);waitKey(0);destroyAllWindows();return 0;
}

运行得:

3.2、图像尺寸变换

在opencv4中提供resize()函数用于修改成指定尺寸。
调用格式resize(row_image,out_image,out_size,w_ratio,h_ratio,method)
row_image:输入的图像
out_image:输出的图像
out_size:改变后的图像的大小
w_ratio:w的比例因子,如果将水平轴变成原来的两倍,则赋值2
h_ratio:h的比例因子,同上
method:改变图像尺寸用的方法,比如缩小图像,就相当于一个下采样,要怎么下采样,比如扩大图像,就需要填充像素,该用什么方法填充像素。一般缩小用INTER_AREA,放大用双三次插值INTER_CUBIC

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {//读取图像Mat im = imread("E:\\opencv_study\\opencv_study.png");//获取图像长宽int w = im.size().width;int h = im.size().height;Mat im_up, im_dn;//放大、缩小图像(改变图像尺寸)resize(im, im_up, Size(w * 2, h * 2), 0, 0, INTER_CUBIC);resize(im, im_dn, Size(w / 2, h / 2), 0, 0, INTER_AREA);imshow("放大图像", im_up);imshow("缩小图像", im_dn);waitKey(0);destroyAllWindows();return 0;
}

运行得

3.3、图像翻转变换

opencv4中使用flip()函数实现图像翻转。
调用格式:flip(row_image,out_image,method)
row_image:输入图像
out_image:输出图像
mehod:翻转方式,大于0表示绕y轴翻转,等于0表示按x轴翻转,小于0表示按x轴跟y轴翻转.

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {//读取图像Mat im = imread("E:\\opencv_study\\opencv_study.png");Mat im_x, im_y, im_xy;//翻转图像flip(im, im_x, 0);flip(im, im_y, 1);flip(im, im_xy, -1);imshow("原图像", im);imshow("绕x轴旋转", im_x);imshow("绕y轴旋转", im_y);imshow("绕x,y轴旋转", im_xy);waitKey(0);destroyAllWindows();return 0;
}

3.4、图像仿射变换

opencv4使用getRotationMatrix2D()函数计算旋转矩阵,getAffineTransform()通过三个对应点求变换矩阵,warpAffine()函数实现图像的仿射变换,仿射变换就是线性变换+平移,可以保证图像的平行线不变,面积的比值不变。。想仔细了解建议自行百度。
调用格式:
rotation=getRotationMatrix2D(center,angle,scale)
rotation=getAffineTransform(row_point,new_point)
warpAffine(row_image,out_image,rotation,size,flags,border_mode,border_value)
其中:
rotation:旋转矩阵,getRotationMatrix2D函数的返回值,是一个2×3的矩阵。
center:图像旋转的中心位置
angle:图像旋转角度,正值为逆时针旋转,单位为度。
scale:两个轴的比例因子,可以实现缩放,不缩放为1.
row_point:源图像中三个点的坐标
new_point:目标图像中三个点的对应坐标
row_image:原图像
out_image:输出图像
size:输出图像的大小
flags:插值方法标志
border_mode:像素边界外推方法标志
border_value:填充值,默认为0

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {//读取图像Mat im = imread("E:\\opencv_study\\opencv_study.png");int w = im.size().width;int h = im.size().height;Point2f center(w / 2, h / 2);double angle = 60;Mat rotation = getRotationMatrix2D(center, angle, 1);Mat im_out1,im_out2;Point2f row_point[3], new_point[3];row_point[0] = Point2f(0, 0);row_point[1] = Point2f(0, h);row_point[2] = Point2f(w, 0);new_point[0] = Point2f(0.11*w, 0.2*h);new_point[1] = Point2f(0.15*w, 0.6*h);new_point[2] = Point2f(0.7*w, 0.3*h);Mat rotation2 = getAffineTransform(row_point, new_point);warpAffine(im, im_out1, rotation, Size(w, h));warpAffine(im, im_out2, rotation2, Size(w, h));imshow("原图像", im);imshow("仿射变换", im_out1);imshow("仿射变换2", im_out2);waitKey(0);destroyAllWindows();return 0;
}

运行得:

3.5、图像透视变换

透视变换就是将物体重新投影到新的成像平面,比如摄像机成像,就死透视变换,在opencv4中,使用getPerspectiveTransform函数和warpPerspective函数进行图像的透视变换。
调用格式:
ratation=getPerspectiveTransform(row_point,new_point,method)
warpPerspective(row_image,out_image,rotation,size,flags,border_mode,border_value)
其中:
row_point:原图像的四个像素坐标
new_point:目标图像的四个像素坐标
method:计算透视矩阵的方法
ratation:变换矩阵
row_image:输入图像
out_image:输出图像
size:输出图像大小
flags:插值方法标志
border_mode:像素边界外推方法标志
border_value:填充值,默认为0

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {//图像读取Mat im = imread("E:\\opencv_study\\opencv_study.png");int w = im.size().width;int h = im.size().height;Point2f row_image[4], new_image[4];row_image[0] = Point2f(0, 0);row_image[1] = Point2f(0, h);row_image[2] = Point2f(w, 0);row_image[3] = Point2f(w, h);new_image[0] = Point2f(0.2*w, 0.2*h);new_image[1] = Point2f(0.2*w, 0.6*h);new_image[2] = Point2f(0.7*w, 0.3*h);new_image[3] = Point2f(0.8*w, 0.8*h);Mat rotation = getPerspectiveTransform(row_image, new_image);Mat im_out;warpPerspective(im, im_out, rotation, Size(w, h));imshow("原图像", im);imshow("透视变换", im_out);waitKey(0);destroyAllWindows();return 0;
}

运行得:

4、绘制几何图形

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;int main() {Mat im = Mat::zeros(Size(512, 512), CV_8UC3);circle(im, Point(50, 50),25, Scalar(255, 255 ,0), -1);//绘制实心圆circle(im, Point(50, 20), 25, Scalar(255, 255, 0), 3);//绘制空心圆line(im, Point(100, 100), Point(200, 100), Scalar(255, 255, 255), 2, LINE_4);//绘制直线ellipse(im, Point(300, 250), Size(100, 70), 0, 0, 360, Scalar(0, 0, 255), -1);//绘制椭圆rectangle(im, Rect(200, 150, 100, 60), Scalar(0, 255, 255), -1);//绘制矩形Point p[5];p[0] = Point(350, 80);p[1] = Point(460, 90);p[2] = Point(500, 170);p[3] = Point(420, 190);p[4] = Point(340, 140);const Point *pts[1] = { p };int npts[] = { 5 };fillPoly(im,pts,npts,1, Scalar(0, 255, 255), 8);//绘制多边形putText(im, "TEST", Point(100, 100), 2, 1, Scalar(255, 0, 255));//绘制文字imshow("图像显示", im);waitKey(0);destroyAllWindows();return 0;
}

运行得:

5、窗口交互操作

交互操作主要有两个,一个是图像窗口滑动,一个是鼠标响应,在opencv4中,使用createTrackbar函数实现图像窗口滑动,使用setMouseCallback函数实现鼠标响应。
调用格式:
createTrackbar(trackname,winname,value,max_value,callback,user_data)
setMouseCallback(winname,mouse_callback,mouse_data)
其中:
trackname:滑动条名称
winname:窗口名称
value:指向整数变量的指针,该指针指向的值反映滑块的位置,创建后,滑块位置由此变量定义。
max_value:滑动的最大值
callback:回调函数
user_data:传递给回调函数的可选参数
mouse_callback:鼠标响应的回调函数
mouse_data:传递给鼠标响应回调函数的可选参数

# include<iostream>
#include<opencv.hpp>using namespace std;
using namespace cv;
int value;
Mat im, im2;
Point prepoint;
static void callback(int ,void*) {float a = float(value) / 100;im2 = im * a;imshow("图像显示", im2);
}
static void mouse(int event, int x, int y, int flags, void *) {if (event == EVENT_MOUSEMOVE && (flags&EVENT_FLAG_LBUTTON)) {im.at<Vec3b>(y, x) = Vec3b(0, 0, 255);im.at<Vec3b>(y+1, x) = Vec3b(0, 0, 255);im.at<Vec3b>(y, x+1) = Vec3b(0, 0, 255);im.at<Vec3b>(y-1, x) = Vec3b(0, 0, 255);im.at<Vec3b>(y, x-1) = Vec3b(0, 0, 255);imshow("图像显示", im);}
}
int main() {im = imread("E:\\opencv_study\\opencv_study.png");value = 100;imshow("图像显示", im);createTrackbar("亮度百分比", "图像显示", &value, 600, callback, 0);setMouseCallback("图像显示", mouse, 0);waitKey(0);destroyAllWindows();return 0;
}

运行得,按住左键可在图上画图案。

opencv-4学习(三)图像的基本操作相关推荐

  1. OpenCV Java入门三 Mat的基本操作

    环境好了,我们就可以进入正文了. 在之前入门一.二中分别已经有画图的两个例子了.但没有细节展开我们的代码和OpenCV到底在干什么. 使用OpenCV时你需要补充的知识 你需要熟练使用Java Swi ...

  2. opencv3 学习三 - 图像输入输出显示等

    程序如下 #include "opencv2/opencv.hpp" using namespace cv;int main() {Mat file1 = imread(" ...

  3. Opencv的学习之图像滤波

    python的代码展示 import cv2 import matplotlib.pyplot as pltimg = cv2.imread(r'C:\Users\master\Desktop\HHH ...

  4. OpenCV与图像处理学习六——图像形态学操作:腐蚀、膨胀、开、闭运算、形态学梯度、顶帽和黑帽

    OpenCV与图像处理学习六--图像形态学操作:腐蚀.膨胀.开.闭运算.形态学梯度.顶帽和黑帽 四.图像形态学操作 4.1 腐蚀和膨胀 4.1.1 图像腐蚀 4.1.2 图像膨胀 4.2 开运算与闭运 ...

  5. OpenCV与图像处理学习五——图像滤波与增强:线性、非线性滤波、直方图均衡化与Gamma变换

    OpenCV与图像处理学习五--图像滤波与增强:线性.非线性滤波.直方图均衡化与Gamma变换 三.图像滤波与增强 3.1 线性滤波 3.1.1 方框滤波 3.1.2 均值滤波 3.1.3 高斯滤波 ...

  6. 【opencv学习笔记】003之图像像素基本操作(获取像素指针、范围处理)及掩膜操作(filter2D)详解

    目录 一.前言 二.图像像素基本操作 1.获取图像像素指针 1.获取图像像素指针是什么? 2.相应API 3.获取目的 2.像素范围处理saturate_cast 1.像素范围处理是什么? 2.像素范 ...

  7. Opencv学习笔记——图像基本操作

    文章目录 前言 一.数据读取-图像 1.读取图像 2.读取部分图像 二.数据读取-视频 三.颜色通道提取 四.边界填充 五.数值计算 六.图像融合 前言 先说一些图像的基本知识: (1)图像由像素构成 ...

  8. python opencv 图像切割_【OpenCV+Python】图像的基本操作与算术运算

    图像的基本操作 在上个教程中,我们介绍了使用鼠标画笔的功能.本次教程,我们将要谈及OpenCV图像处理的基本操作. 本次教程的所有操作基本上都和Numpy相关,而不是与OpenCV相关.要使用Open ...

  9. OpenCV与图像处理学习三——线段、矩形、圆、椭圆、多边形的绘制以及文字的添加

    OpenCV与图像处理学习三--线段.矩形.圆.椭圆.多边形的绘制以及文字的添加 一.OpenCV中的绘图函数 1.1 线段绘制 1.2 矩形绘制 1.3 圆绘制 1.4 椭圆的绘制 1.5 多边形绘 ...

  10. opencv4 c++ 提取图片中的白色区域_修正!【从零学习OpenCV 4】分割图像——分水岭法...

    点击上方"小白学视觉",选择"星标"公众号重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开 ...

最新文章

  1. 是什么阻碍了你的 AI 致富路?
  2. oracle 查询历史sql执行最慢和执行次数最多的sql
  3. perl开发环境配置(Database,SOCKET,CISCO)j(ReShip)
  4. C#DataGrdviewl加入checkBox全选删除
  5. js中every用法_js数组中的方法 some, every, filter, find,map, reduce讲解及使用场景
  6. verilog中的综合与不可综合
  7. hashset java api_java常用对象API中集合框架之HashSet
  8. [转]Sublime Text 2 C++编译运行简单配置
  9. SQL Server JSON:性能手册
  10. idea 快捷删除移动_21个极大提高开发效率的VS Code快捷键
  11. opencv 读取视频、打开摄像头、写入视频文件
  12. java netty rpc框架_Java编写基于netty的RPC框架
  13. driver nvidia web_黑苹果 macOS 10.13.6 17G66 安装 nVidia WebDriver
  14. 数据分析之matplotlib和numpy的应用
  15. 笔记-JavaScript高级程序设计-第六章思维导图
  16. 在设计四人抢答器中灯全亮_EDA课程设计—四人抢答器设计
  17. Python调用百度API实现人脸融合
  18. 记录一次生产环境偶发HTTP响应406报错问题
  19. 岩板铺地好吗_铺地的石板如何用处高逼格,三个大师案例来教你!
  20. 洛谷P1000 超级玛丽游戏c语言基础

热门文章

  1. HBuilder配置谷歌浏览器路径无法正常使用情况
  2. mysql 多表并列查询_MySQL多表查询
  3. 数字档案馆建设指南现【代化智慧档案馆建设】
  4. 恶意软件向云伸出魔爪,云端智能如何谈起?
  5. 小红书“种草”潮玩生意
  6. Android中颜色值的坑
  7. 计算机毕业设计springboot的网上社区团购平台的设计与实现4ptp89【附源码+数据库+部署+LW】
  8. python实现获取毫秒级时间戳
  9. Leetcode 刷题目录
  10. 使用Ganache、web3.js和remix在私有链上部署并调用合约