opencv的个人理解

opencv代码:

#include<opencv2\opencv.hpp>

#include<iostream>

using namespace cv;

using namespace std;

int main(int argc,char** argv){

Mat src=imread("E:/cat.jpg");

imshow("input",src);

waitKey(0);

destroyAllWindows();

return 0;

}

学习读取图像和显示图像两个函数imread和imshow

imread是读取一张图像实际上有两个参数

im就是英文image

imread("默认输入的地址/路径")

所有的图像都是Mat图像本身来说,大多数都是二维数组也叫二维矩阵,所以用Mat来表示

imshow与他对应;

imshow也有两个名称,第一个呢是表示窗口名称,“input”这个窗口,src表示数据对象

waitKey是一个比较重要的参数,waitKey(0),0表示阻塞;表示程序停止,从而使得图片一直显示在运行上面如果改成1表示,停顿一毫秒继续往下执行,

destroyAllWindows表示把前面全部创建的窗口销毁掉,

如果显示图片很大,不能去完全展示就应该加一个函数叫

namedWindow("输入窗口",WINDOW_FREERATIO);其中的"输入窗口"应该与imshow的第一个函数相同,使得图片可以自由缩放;

把图片加载为黑白的函数为:Mat src=imread("E:/cat.jpg",IMREAD_GRAYSCALE);

src表示三通道,每个通道是一个字节,一个字节是八个比特位,这个图深度就是24;

opencv会以枚举的方法展示

一般会加代码if语句:

if(src.empty())//判断是否为空白)//是空白就不能加载然后返回显示下面代码

{

printf("could not load image...\n");

return -1;

}

第二课学习保存图像,处理图像

学习函数cvtColor(色彩空间转换函数)

和图像保存-imwrite

1.cvtColor函数包括:

COLOR_BGR2GRAY=6表示色彩到灰度;

COLOR_GRAY2BGR=8表示灰度到彩色;

COLOR_BGR2HSV=40由BGR到HSV;

COLOR_HSV2BGR=54由HSV到BGR;

2.图像保存-imwrite

第一个参数是图像保存路径;

第二个参数是图像内存对象;

可以先编写头文件;先将头文件命名,然后更改所用函数路径使得函数可直接调用此头文件,然后就可进行下面操作,使用代码三个

一主函数,二函数,三头文件。

一主#include<opencv2\opencv.hpp>

#include<quickopencv.h>

#include<iostream>

using namespace cv;

using namespace std;

int main(int argc, char** argv) {

Mat src = imread("E:/11.jpg");

namedWindow("input",WINDOW_FREERATIO);

imshow("input", src);

QuickDemo qd;

qd.colorSpace_Demo(src);

waitKey(0);

destroyAllWindows();

return 0;

}

二函

#include<quickopencv.h>

#include <iostream>

#include<opencv2\opencv.hpp>

using namespace std;

void QuickDemo::colorSpace_Demo(Mat &image)

{

Mat gray, hsv;

//cout << image << endl;

cvtColor(image, hsv, COLOR_BGR2HSV);

cvtColor(image, gray, COLOR_BGR2GRAY);

imshow("HSV", hsv);

imshow("灰度", gray);

imwrite("D:/hsv.png", hsv);

imwrite("D:/gray.png", gray);

}

三头(头文件)

头文件的后缀为:.h

可在头文件中命名也可在文件中命名。只需要把后缀改为.h就行

#pragma once

#include<opencv2/opencv.hpp>

using namespace cv;

class QuickDemo {

public:

void colorSpace_Demo(Mat &image);

};

当运行时显示三张图片时表示运行成功,

imread后面所跟的地址中的斜杠为/

也可以从你所保存的地址中用windows的图片显示器来显示

注意imshow只支持8位或者说是256位的那种显示,要不就是支持浮点数的显示,如果显示其他类型,多少有点问题,用imread读进来的一定是8位的前提是读进来后没有发生转换

8位通道的顺序是B,G,R分别表示颜色蓝,绿,红

HSV也是三个通道,H通道范围在(0~180)S,V的通道都在(0~255)h,s表示颜色,v表示亮度,s可以调整颜色的饱和度

第三节

学习Mat函数的使用

有很多属性操作也会有很多的自身变量的操作

Mat对象的使用分在:

1.读进来的图像是Mat我们如何去操作他

2.Mat本身我们如何便利访问他的每个数点

3.我们如何去创建一个空的图像或者是Mat

4.创建时有什么方法,用什么方法

Mat如何创建:

Mat分为两个部分,一个部分名为头部,另一个部分名为数据部分,数据部分就是所有像素的一个值的集合,通道大部分都在头部的原数据中获取,重新赋值就是把指针给原来的数组,本质上没有发生变化还是指向同一个数据部分,只有你进行克隆或者拷贝时,这时才会把数据重新赋值给另一个指针

Mat m3 = Mat::ones(Size(8,8), CV_8UC1)的cv_8uc1中,必须是1,如果写3,则数据将会变更成只限制第一行数据,第二第三行还是0,他不会把所有限速点都限制为1,只会把每个限速点的第一个通道初始化为1。如果你想使三个都变成127,则需要用一个函数Scalar,把m3=Scalar(127,127,127);定义

注意所用通道模式,不能将CV_8UC1三通道CV_8UC3的形式使用,将会使(255,0,0)不显示蓝色图像,只会按灰色,黑色,白色,三种颜色,

色彩空间转换,rgb,hsv,和灰度色彩空间,加载图像等,一切图像皆Mat,如何创建空图像,找到所创建的图像大小,且知道了颜色。

如何在创建图像之后,给每一个像素点进行赋值呢?

学习图像像素的读写操作,在c++中可使用数组遍历,也可使用指针方式遍历

指针和数组下标不一样,指针根据类曾地址进行访问,可以比数组下标快一点,

第二周

第4节

修改图像的数据类型,如何将数据类型进行转换,后面有Mat,需要继续转换,字节类型的单通道灰度图像dims=1,dims=3(是彩色图像),如何获取彩色像素的像素点,比如告诉你他的一个点(0,0),其中的row位置表示行,col位置表示列,列是宽度,行是高度。三通道时也可以获取,但三通道时就不是这个数值了,则用image.at<Vec3b>专门获取三通道时的彩色图像像素点处理,如果是int呢那就是Vec3i,如果是浮点数就是Vec3f,所以是:Vec3b bgr =image.at<Vec3b>(row,col);

//可以一次性存储三个值

图像转化,简单说就是图像反色,数组的便利读写基于数组的下标,也可以用指针来完成。

按指针形式完成需要在for循环中定义一个指针,因为数据类型为uchar所以指针类型为uchar定义完指针之后如何进行改变呢?就是将for循环中的原来数值更改为指针,使得代码数量大大减少,且运行时间更快

将这种形式改成指针形式为

学习图像像素的操作,像素的加减乘除操作;

Mat对于加减乘除都能接受,

当图像加上50之后,表明图像的每个像素点都增加50使得表面看起来更加光亮,

当图像减去50之后,图像的颜色和之前的原图相比,变得暗淡。注意:数值应该在0到255之间超过255数值只能是255,低于0也就是0,不能超过值域。

运行出现的图像为:

除法图像为:

乘法时运行:乘法时乘积超过255会报错,和数据类型不同的数据相乘时,数据的数值会报错,所以要想使得乘法运算成立,则需要改变所用数据的数据类型,但是仅仅改变数据类型是不可以的,还需要使用一种函数(multiply(第一个图像,第二个图像,应该生成的图像))使得图像与图像之间可以相乘

运行出后为:

代码运行过程为:

int w = image.cols;

int h = image.rows;

int dims = image.channels();

for (int row = 0; row < h; row++) {

for (int col = 0; col < w; col++) {

if (dims == 1) {//灰度图像

int pv = image.at<uchar>(row, col);

image.at<uchar>(row, col) = 255 - pv;

}

if (dims == 3) {//彩色图像

Vec3b bgr = image.at<Vec3b>(row, col);

image.at<Vec3b>(row, col)[0] = 255 - bgr[0];

image.at<Vec3b>(row, col)[1] = 255 - bgr[1];

image.at<Vec3b>(row, col)[2] = 255 - bgr[2];

}

}

}

因为知道这个代码是三通道的所以可以把代码改成:

for (int row = 0; row < h; row++) {

for (int col = 0; col < w; col++) {

Vec3b p1 = image.at<Vec3b>(row, col);//因为所定义的m与image大小完全一致就可以用m代替image

Vec3b p2 = image.at<Vec3b>(row, col)

image.at<Vec3b>(row, col)[0] = 255 - bgr[0];

image.at<Vec3b>(row, col)[1] = 255 - bgr[1];

image.at<Vec3b>(row, col)[2] = 255 - bgr[2];

}

}因为把image赋给了dst所以可以用dst代替image,且有p1和p2所以可把代码改写成:

for (int row = 0; row < h; row++) {

for (int col = 0; col < w; col++) {

Vec3b p1 = image.at<Vec3b>(row, col);//因为所定义的m与image大小完全一致就可以用m代替image

Vec3b p2 = image.at<Vec3b>(row, col);

dst.at<Vec3b>(row, col)[0] = p1[0] + p2[0];

dst.at<Vec3b>(row, col)[1] = p1[1] + p2[1];

dst.at<Vec3b>(row, col)[2] = p1[2] + p2[2];

}

}

但是如果说p1和p2的值超过了一百这样的话,数值就会发生变化,所以应该使用一个函数;saturate_cast<数据类型>(p1[0]+p2[0]);这个函数的意思是可以对这个数值加和做一个数值判定,必须在数据类型比如:uchar,的范围内,如果小于0就是0,如果大于255,那就是255。这样就能把数据限定在0-255之间,这个函数在数据转型时,比如int变成double,等经常用到,需要记住这个函数,常用函数。所以这段代码改成:

dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(p1[0] + p2[0]);

dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>( p1[1] + p2[1]);

dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(p1[2] + p2[2]);

可以用add为加函数代替:

divide为除函数,除的数值较大的话,图像会变成黑色。

学习Trackbar函数,施行滚动条演示操作:

运用这个函数时候,系统会自动补充这个数值,但是想自己填写,应该自己更改数值,不用的话直接转型就行

因为你有了track这个函数,所以你可以直接调用,比如说你调用出来可以直接赋值运算,

因为执行有顺序问题,所以赋值的话先定义完放在最上面,

tracked bar

亮度调整操作 指针变成MAT类型使用on track 用形参进行定义 用scalar进行调整可使

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值