Mat imread( const String& filename, int flags = IMREAD_COLOR );
返回值: Mat 类型
filename: 图片的路径
flags: 读取图片的模式 默认为 IMREAD_COLOR
flage 的常用类型有:
flage | 意思 |
---|---|
IMREAD_UNCHANGED | 按照图片原有的样子读取 |
IMREAD_GRAYSCALE | 转换成单通道灰色图 |
IMREAD_COLOR | 把图片转换成三通道RGB彩色图像 |
例子
Mat src = imread("E:\\opencv_tutorial_data-master\\opencv_tutorial_data-master\\images\\yuan_test.png",IMREAD_UNCHANGED);
//判断读取的图像是否为空
if (src.empty() )
{
cout << "读取图片错误" << endl;
return 0;
}
void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);
返回值: 空
winname: 窗口的名字
flags: 窗口的模式 默认为 WINDOW_AUTOSIZE
flags 常用类型
flags | 意思 |
---|---|
WINDOW_AUTOSIZE | 自动大小,根据图片的大小确定窗口的大小 |
WINDOW_FULLSCREEN | 窗口大小充满整个屏幕 |
WINDOW_FREERATIO | 自动大小,用户可以任意调整窗口的大小 |
WINDOW_KEEPRATIO | 窗口的大小,根据图片的比例进行确定 |
void imshow(const String& winname, InputArray mat);
返回值: 空
winname: 窗口的名字
mat: 需要显示图像
根据 winname
,确定sc
显示在那个窗口
void destroyAllWindows(); 销毁任何窗口
void destroyWindow(const String &winname); 销毁指定的窗口,根绝winname决定销毁那个窗口
返回值: 空
winname: 窗口的名字
这两个函数基本上都是和 namedWindow
API进行联合使用
例子
//读取磁盘里的图片
Mat src = imread("E:\\opencv_tutorial_data-master\\opencv_tutorial_data-master\\images\\yuan_test.png",IMREAD_UNCHANGED);
//判断读取的图片是否为空
if (src.empty() ||src1.empty())
{
cout << "读取图片错误" << endl;
return 0;
}
//创建显示图片的窗口
namedWindow("输入窗口", WINDOW_FREERATIO);
//显示图片 显示到-->输入窗口
imshow("输入窗口", src);
//按任意键结束
waitKey();
//销毁所有的窗口
destroyAllWindows();
return 0;
int waitKey(int delay = 0);
返回值: int类型的 ASCLL码
delay: 等待多长时间
waitKey ,等待一个按键事件,可以无限的或指定多少秒,当delay=0则表示无限等待,当delay>0则表示等待多少秒.他会返回你按键的ASCLL码值,但当你指定一个时间,但没有按键事件则返回-1
列子: 当按下Esc
退出整个程序,按下1
把颜色空间转换成HSV空间,按下2
把3通道的彩色编程单通道的灰色图片
//读取图片
Mat src = imread("E:\\opencv_tutorial_data-master\\opencv_tutorial_data-master\\images\\yuan_test.png");
//创建一个和src大小类型相等值为零的Mat
Mat dst ;
//检查是否争取读取图片
if (src.empty())
{
cout << "读取图片错误" << endl;
return 0;
}
//创建显示窗口
namedWindow("输入窗口", WINDOW_FREERATIO);
//在输入窗口显示图片
imshow("输入窗口", src);
while (true)
{
//等待一个按键事件
char c = waitKey();
cout << "您输入的是: " << c << endl;
if (c == 27)
{
break;
}
if (c == '1')
{
cvtColor(src, dst, COLOR_BGR2HSV);
imshow("输入窗口", dst);
}
if (c == '2')
{
cvtColor(src, dst, COLOR_BGR2GRAY);
imshow("输入窗口", dst);
}
}
//等待键盘事件
waitKey();
destroyAllWindows();
return 0;
void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
返回值: 空
src: 原图像
dst:结果图像
code: 色彩空间转换模式
dstCn:结果图像的通道数,默认为0,当不写通道数则把原图像的通道数拷贝到结果图像中
code 常用模式:
code | 意思 |
---|---|
COLOR_BGR2BGRA | 向RGB图片中添加alpha通道 |
COLOR_BGRA2BGR | 删除alpha通道 |
COLOR_BGR2GRAY | 转换成灰色图片 |
COLOR_GRAY2BGR | 灰色转换成BGR |
COLOR_GRAY2RGB | 灰色转换成RGB |
COLOR_BGR2HSV | BGR转换成HSV色彩空间 |
例子:把彩色图片转换成HSV或者是 gray灰色图片,请看waitKey
的相关代码
例子:对原图进行加减法,加上一个(50,50,50)的图像,对原图乘除以(2,2,2)的图像
void Demo::operation_(Mat &src)
{
Mat addIm;
Mat subIm;
Mat multiIm;
Mat diviIm;
//创建显示窗口
namedWindow("addIm", WINDOW_FREERATIO);
namedWindow("subIm", WINDOW_FREERATIO);
namedWindow("multiIm", WINDOW_FREERATIO);
namedWindow("diviIm", WINDOW_FREERATIO);
//创建一幅图片
Mat m1 = Mat::zeros(src.size(), src.type());
m1 = Scalar(50, 50, 50);
//addIm=src+m1
add(src, m1, addIm);
imshow("addIm", addIm);
//subIm = src - m1;
subtract(src, m1, subIm);
imshow("subIm", subIm);
m1 = Scalar(2, 2, 2);
//multiIm=src*m1
multiply(src, m1, multiIm);
imshow("multiIm", multiIm);
//diviIm = src / m1;
divide(src, m1, diviIm);
imshow("diviIm", diviIm);
}
int createTrackbar(
const String &trackbarname,
const String &winname,
int *value,
int count,
TrackbarCallback onChange = 0,
void *userdata = 0
);
返回值: int 0表示创建失败,1表示创建成功
trackbarname: 滑动条的名称
winname: 窗口的名字,根据窗口的名字进行确定滑动条添加到那个窗口
value: 滑动条的初始值
count:滑动条的最大值
onChange: 滑动条回调函数
userdata: 给滑动条回调函数传递的参数
例子:通过改变滑动条,来改变图片的对比度
可以看出随着滑动条数值越来越大,两张图片的对比越来越明显,亮的地方越来越亮
//回调函数
void callback(int pos, void *userdata)
{
Mat src = *((Mat *) userdata);
Mat blank = Mat::zeros(src.size(), src.type());
Mat dst;//接受结果图像
double position = pos/100.0;
addWeighted(src, position, blank, 0, 0, dst);
imshow("输出窗口", dst);
}
void Demo::color_tracking(Mat &src)
{
int number = 100;
namedWindow("输出窗口", WINDOW_FREERATIO);
//创建一个滑动条,可以在一个窗口创建多个滑动条
int result = createTrackbar("对比度", "输出窗口", &number,500, callback, &src);
cout << result << endl;
callback(10, &src);
}
void applyColorMap(InputArray src, OutputArray dst, int colormap);
返回值:空
src:原图像
dst: 用于接受结果的图像
colormap: 设置应用的颜色类型 也可以自定义颜色
例子: 循环应用不同的色彩样式按’1’进行切换,按’Esc’退出
void colorStyle(Mat &src)
{
// 需要应用的颜色样式
int style[] = {
COLORMAP_AUTUMN,
COLORMAP_BONE,
COLORMAP_JET,
COLORMAP_WINTER,
COLORMAP_RAINBOW,
COLORMAP_OCEAN,
COLORMAP_SUMMER
};
//创建一个空白图像用于接受结果
Mat dst = Mat::zeros(src.size(), src.type());
namedWindow("输出窗口", WINDOW_FREERATIO);
char c;
int i = 0;
//循环应用不同的色彩样式按'1'进行切换,按'Esc'退出
while (true)
{
c = waitKey(10);
if (c == 27)
{
break;
}
if (c == '1')
{
applyColorMap(src, dst, i % (sizeof(style) / sizeof(int)));
cout << "您的按键是 " << c << endl;
i++;
imshow("输出窗口", dst);
}
}
return 0;
}
void split(const Mat& src, Mat* mvbegin);
返回值: 空
src:原图像
mvBegin:数组指针的起始地址
例子: 把一个彩色3通道的图像分解成3个单通道的图片
上面的图像是分解的结果,为什么会出现三个灰色图像呢,因为他们都是单通道的,所以表现出来的就是灰色图像我们可以把他们的颜色显示出来
void splitChannels(Mat &src)
{
Mat *mv = new Mat[3];
Mat blue;
Mat green;
Mat red;
Mat dst;
//分解图像通道
split(src, mv);
//如果分离的通道不为空则显示他们
if (!mv[0].empty())
{
cout << mv[0].rows << " " << mv[0].cols << mv[0].channels() << endl;
namedWindow("blue", WINDOW_FREERATIO);
imshow("blue", mv[0]);
}
if (!mv[1].empty())
{
namedWindow("green", WINDOW_FREERATIO);
imshow("green", mv[1]);
}
if (!mv[2].empty())
{
namedWindow("red", WINDOW_FREERATIO);
imshow("red", mv[2]);
}
//把绿色红色通道颜色设置为0 ,以显示蓝色
mv[1] = mv[2] = 0;
// 把三张单通道图片合成一张三通道图像
merge(mv, 3, dst);
imshow("输出窗口", dst);
//释放内存
delete [] mv;
}
void merge(const Mat* mv, size_t count, OutputArray dst);
返回值: 空
mv:单通道图片的数组首地址
count: 数组的大小
dst: 结果图片
例子:请看split函数例子的蓝色图像
void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);
返回值:空
src: 原图像
lowerb: 颜色范围的下界
upperb: 颜色范围的上界
dst:结果图像
二值化的意思:如果原图像的颜色在指定范围内则把这些颜色设置为255,否则为0
//回调函数
void callLHmin(int pos, void *userdata){
Mat dst;
inRange(src, Scalar(pos, 43, 46), Scalar(180, 255, 255), dst);
imshow("输出窗口", dst);
}
void Demo::inrange(Mat &src)
{
::src = src;
Mat hsv;
namedWindow("输出窗口", WINDOW_FREERATIO);
//把图像转换成HSV空间下进行处理
cvtColor(src, hsv, CV_BGR2HSV);
//创建一个滑动条
createTrackbar("LHmin", "输出窗口", 0, 180, callLHmin);
return;
}
void resize( InputArray src, OutputArray dst,Size dsize, double fx = 0, double fy = 0,int interpolation =INTER_LINEAR );
返回值: 空
src: 原图片
dst: 结果图片 ,在重置图片大小的时候dst初始的大小和类型将被忽略,大小和类型从src中计算出
dsize: 结果图片的大小 ,如果Size=null或0结果图片的大小将从fx和fy中计算
fx: x轴方向的比例因子 ,如果fx=0则 fx=dsize.width/src.cols
fy: y轴方向的比例因子 ,如果fy=0则 fy=dsize.height/src.rows
interpolation: 插值器
注意 dsize 和fx,fy不能同时为零
,缩小图片 插值器使用INTER_AREA
比较好,放大图片使用INTER_CUBIC
或 INTER_LINEAR
比较好
例子: 缩小一张图片
void myResize(Mat &src)
{
Mat dst;
//fx,fy方向等比缩小0.5倍
//resize(src,dst,Size(),0.5,0.5);
resize(src,dst,Size(256,256));
imshow("输出窗口", dst);
}
Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
返回值:Mat
shape: 形状
ksize: 元素结构的大小
anchor: 锚点的位置 只有 十字形状(cross-shaped)依赖这个锚点,其余现状只表示偏移量
注意:`这个函数返回的结果可以传递给erode,dilate或morphologyEx函数
shape的类型
shape | 意思 |
---|---|
MORPH_RECT | 矩形 |
MORPH_CROSS | 十字型 |
MORPH_ELLIPSE | 椭圆形 |
例子:获取一个20*10的正方形
Mat erodeElement = getStructuringElement(MORPH_RECT, Size(20, 10));
double threshold( InputArray src, OutputArray dst,double thresh, double maxval, int type );
返回值: 如果使用 `THRESH_OTSU`或 `THRESH_TRIANGLE`类型返回计算的阈值
src:输入的图像
dst:结果图片 大小类型和src一样
thre: 阈值
maxvalue: 使用类型`THRESH_BINARY` 或`THRESH_BINARY_INV`则把满足阈值的像素设置为这个值
type:阈值的类型
void callback(int pos, void *userdata)
{
Mat src = *((Mat *) userdata);
cvtColor(src, src, COLOR_BGR2GRAY);
Mat dst;
//二值化
threshold(src, dst, pos, 255, THRESH_BINARY);
imshow("输出窗口", dst);
}
int main()
{
namedWindow("输入窗口", WINDOW_FREERATIO);
namedWindow("输出窗口", WINDOW_FREERATIO);
//创建滑动条
createTrackbar("二值化", "输出窗口", 0, 255, callback, &src);
imshow("输入窗口", src);
waitKey();
destroyAllWindows();
return 0;
}
通过指定元素的结构去侵蚀原图像
void erode( InputArray src, OutputArray dst, InputArray kernel,
Point anchor = Point(-1,-1), int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue() );
返回值: 空
src: 输入的图像,通道数可以是任意的但是深度应该是CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
dst:结果图像 和src的大小类型相同
kernel: 侵蚀所使用的的元素结构,kernel可以使用`getStructuringElement`函数获取
anchor: 在元素内锚点的位置,默认值(-1,-1)表示锚点的中心位置
iterations: 侵蚀的次数
borderType 像素外推方法
borderValue: 像素外推的值 只在常量中有效
void myErode(Mat &src){
Mat dst;
namedWindow("输入窗口", WINDOW_FREERATIO);
imshow("输入窗口", src);
namedWindow("二值化窗口", WINDOW_FREERATIO);
cvtColor(src, dst, COLOR_BGR2GRAY);
//对图像进行二值化
threshold(dst, dst, 140, 255, THRESH_BINARY);
imshow("二值化窗口", dst);
//侵蚀 获取侵蚀所使用的元素类型
Mat erodeElement= getStructuringElement(MORPH_RECT,Size(20,10));
erode(dst, dst, erodeElement);
namedWindow("腐蚀窗口", WINDOW_FREERATIO);
imshow("腐蚀窗口", dst);
return;
}
void findContours( InputOutputArray image, OutputArrayOfArrays contours,
int mode, int method, Point offset = Point());
image: 输入的图像 他是单通道的图像,大于0的元素认为是1,0为0
contours: 检测轮廓的集合 std::vector >
mode: 检测模式
method 检测方法
offset:偏移量
mode 的模式
mode | 意思 |
---|---|
RETR_EXTERNAL | 只检测最外部的轮廓 |
RETR_LIST | 检测的轮廓放入list中,不组织任何关系 |
RETR_CCOMP | 检测所有轮廓,把他们组织成另个层次,外部和内部 |
RETR_TREE | 检测所有轮廓,并组织完整的结构 |
method 的方法
method | 意思 |
---|---|
CHAIN_APPROX_NONE | 存储任何点 |
CHAIN_APPROX_SIMPLE | 忽略直线,只存储四个点 |
void myFindContours(Mat &src){
Mat dst;
namedWindow("输入窗口", WINDOW_FREERATIO);
imshow("输入窗口", src);
namedWindow("二值化窗口", WINDOW_FREERATIO);
cvtColor(src, dst, COLOR_BGR2GRAY);
//对图像进行二值化
threshold(dst, dst, 100, 255, THRESH_BINARY);
imshow("二值化窗口", dst);
//腐蚀 获取侵蚀所使用的元素类型
Mat erodeElement= getStructuringElement(MORPH_RECT,Size(20,10));
//腐蚀 腐蚀
erode(dst, dst, erodeElement);
namedWindow("腐蚀窗口", WINDOW_FREERATIO);
imshow("腐蚀窗口", dst);
//用于保存矩形坐标点信息的集合
vector<vector<Point>> contours;
//检测轮廓
findContours(dst, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
for (int i = 0; i < contours.size(); ++i)
{
//绘制矩形
Rect rect = boundingRect(contours.at(i));
//会知道原图像上
rectangle(src, rect, Scalar(0, 0, 255),2);
}
namedWindow("轮廓窗口", WINDOW_FREERATIO);
imshow("轮廓窗口", src);
return;
}
void polylines(InputOutputArray img, InputArrayOfArrays pts,
bool isClosed, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0 );
返回值:空
img:输入的图像
pts:Point类型的数组集合
ifClose:多边形是否闭合
color:多边形的颜色
thickness: 多边形边的宽度
linType: 边的类型
shift:缩放比例,默认不缩放
void Demo::DrawablePolygon(){
//创建一个黑色图片
Mat src = Mat::zeros(Size(200, 200), CV_8UC3);
//创建五个点
Point p1(10, 10);
Point p2(35, 35);
Point p3(45, 0);
Point p4(100, 100);
Point p5(150, 150);
//创建一个点的集合
vector<Point> points;
points.push_back(p1);
points.push_back(p2);
points.push_back(p3);
points.push_back(p4);
points.push_back(p5);
//绘制多边形
polylines(src, points, true, Scalar(0, 0, 255), 1,LINE_AA);
namedWindow("绘制窗口", WINDOW_FREERATIO);
imshow("绘制窗口", src);
}
持续更新中....请各位大佬多多指点