opencv---c++

opencv(1)

quickopencv.h

#include <opencv2/opencv.hpp>
using namespace cv;
class quickdemo {
public:
	void colorSpace_Demo(Mat &image);
};

quockdemo.cpp

色彩空间转换函数-cvtColor

#include "quickopencv.h"
void quickdemo::colorSpace_Demo(Mat &image) {
	Mat gray, hsv;
	cvtColor(image, hsv, COLOR_BGR2HSV);
	cvtColor(image, gray, COLOR_BGR2GRAY);
	namedWindow("HSV", WINDOW_FREERATIO);
	imshow("HSV", hsv);
	//色相h:0- 180 饱和度s 亮度v
	namedWindow("灰度", WINDOW_FREERATIO);
	imshow("灰度", gray);
	imwrite("C:/Users/嘻嘻哈哈/Pictures/hsv.png",hsv);//三个参数 第一个是图像保存路径,第二个是图像内存对象
	imwrite("C:/Users/嘻嘻哈哈/Pictures/gray.png", gray);

}

main.cpp

#include<opencv2/opencv.hpp>
#include<iostream>
#include "quickopencv.h"
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
	Mat src = imread("C:/Users/嘻嘻哈哈/Pictures/微信图片_20210929221856.jpg");//由imread读出的照片都是8位的
	namedWindow("输入窗口", WINDOW_FREERATIO);//可调大小的窗口形式
	imshow("输入窗口", src);//只能输出8位的

	quickdemo qd;
	qd.colorSpace_Demo(src);

	waitKey(0);
	destroyAllWindows();
	return 0;
}

opencv(2)

1.怎么操作Mat 以及怎么访问每一个像素点

void quickdemo::mat_creation_demo(Mat &image) {
	Mat m1, m2;
	m1 = image.clone();//克隆
	image.copyTo(m2);//拷贝
	//创建空白图像
	Mat m3 = Mat::zeros(Size(40, 40), CV_8UC3); //CV_8UC1 :(Unsigned无符号的),(1:单通道的)8位
	m3=Scalar(1, 1, 1);//通道赋值,知道几个通道就赋几个值,可通过他修改空白图像颜色
	std::cout << "宽度:" << m3.cols << "高度:" << m3.rows << "通道数:" << m3.channels() << std::endl;
	std::cout << m3 << std::endl;
	imshow("创建图像", m3);


}

CV_8UC1:每个像素点的通道数是1

CV_8UC3:每个像素点的通道数是3

 Mat m3 = Mat::ones(Size(8, 8), CV_8UC1);只会使第一个通道是1;

 m3=Scalar(1, 1, 1);//通道赋值,知道几个通道就赋几个值,可通过他修改空白图像颜色

3.怎么创建一个空图或Mat

Mat之克隆m3.clone():修改m4不会对m3进行修改

Mat之克隆m3.copyTo(m4):修改m4不会对m3进行修改

Mat m3 = Mat::zeros(Size(40, 40), CV_8UC3); 
	m3=Scalar(1, 1, 1);
imshow("图像3", m3);
	Mat m4 = m3.clone();//克隆

	//m3.copyTo(m4);//copyTo复制

	m4 = Scalar(200, 200, 200);
	imshow("图像4", m4);

运行结果:

Mat之赋值m3=m4:修改m4对m3进行修改

imshow("图像3", m3);
	Mat m4 =m3;
	m4 = Scalar(200, 200, 200);
	imshow("图像3", m3);

运行结果:

 前两者相当于深拷贝,后者相当于浅拷贝

重载运算符=是浅拷贝,共享内存空间,互相影响,clone是深拷贝,内存空间不同,相互独立,互不打扰;

opencv(3):对图像像素读写操作

1、基于数组

void quickdemo::pixel_visit_demo(Mat &image) {
	int w = image.cols;//宽,列
	int h = image.rows;//高,行
	int dims = image.channels();//通道数,等于1代表是灰度图像,等于3代表是彩色图像
	for (int row = 0; row < h; row++) {//双重for循环
		for (int col = 0; col < w; col++) {
			if (dims == 1) {//灰度图像
				int pv = image.at<uchar>(row, col);//将像素点转变为int类型,获取到一个值
				image.at<uchar>(row, col) = 255 - pv;//uchar范围:0-255(2的8次方)
			}
			if (dims == 3) {//彩色图像
				Vec3b bgr=image.at<Vec3b>(row, col);//浮点数就是Veb3f,获取到三个值,相当于一个数组
				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];
			}
		}
	}
	imshow("像素读写显示",image);
}

 运行结果:

 2、基于指针:速度要快于数组(i++ 用的巧妙)

void quickdemo::pixel_visit_demo(Mat &image) {
	int w = image.cols;//宽,列
	int h = image.rows;//高,行
	int dims = image.channels();//通道数,等于1代表是灰度图像,等于3代表是彩色图像
	for (int row = 0; row < h; row++) {//双重for循环
		uchar *current_row = image.ptr<uchar>(row);//指针指向这一行,获取这一行的地址
		for (int col = 0; col < w; col++) {
			if (dims == 1) {//灰度图像
				int pv = *current_row;//将像素点转变为int类型,获取到这个地址的值
				*current_row++ = 255 - pv;//++的是列数,即cols
			}
			if (dims == 3) {//彩色图像
				Vec3b bgr = image.at<Vec3b>(row, col);//浮点数就是Veb3f,获取到三个值,相当于一个数组
				*current_row++ = 255 - *current_row;//先减再自加,三行则是对三个通道都进行操作
				*current_row++ = 255 - *current_row;
				*current_row++ = 255 - *current_row;
			}
		}
	}
	imshow("像素读写显示",image);
}

运行结果:与上面图一样

opencv(4):对图像像素算数操作

加减乘除都不会超过255也不会小于0,若超过255则会默认调至255,小于0则默认为0

    multiply(image, m, dst);//乘法
    divide(image, m, dst);//除法
    add(image, m, dst);//加法
    subtract(image, m, dst);//减法

void quickdemo::operators_demo(Mat &image) {
	Mat dst;
	//dst = image + Scalar(50, 50, 50);//加法操作,图像变亮,减法变暗
	//imshow("加法操作",dst);
	//dst = image * Scalar(2, 2, 2);乘法操作,不可直接乘,要用专业函数multiply(乘数1,乘数2,积)
	Mat m = Mat::zeros(image.size(), image.type());//创建一个和传过来的图片大小、类型相同的图像
	m = Scalar(2, 2, 2);
	multiply(image, m, dst);//乘法
	divide(image, m, dst);//除法
	add(image, m, dst);//加法
	subtract(image, m, dst);//减法

	imshow("乘法操作", dst);
}

乘法运行结果:

 opencv(5):滚动条操作演示-调整图像亮度

createTrackbar()函数:通过改变滑动条的位置来改变函数里面变量的值

函数有6个参数:

参数1:轨迹条名字

参数2:窗口名字

参数3:滑块初始位置

参数4:表示滑块达到最大位置的值

参数5:默认值为0,指向回调函数

参数6:默认值为0,用户传给回调函数的数据值

    createTrackbar("Value Bar", "亮度调整", &lightness, max_value, on_track,(void*)(&image));
 

static void on_track(int b, void* userdata) {//回调函数
	Mat image = *((Mat*)userdata);
	Mat dst = Mat::zeros(image.size(), image.type());
	Mat m= Mat::zeros(image.size(), image.type());
	m = Scalar(b, b, b);
	subtract(image, m, dst);
	imshow("亮度调整", dst);
}
void quickdemo::tracking_bar_demo(Mat &image) {
	namedWindow("亮度调整", WINDOW_AUTOSIZE);
	int max_value = 100;
	int lightness = 50;
	createTrackbar("Value Bar", "亮度调整", &lightness, max_value, on_track,(void*)(&image));
	on_track(50, &image);
}

效果展示:

 addWeighted()函数是将两张相同大小,相同类型的图片融合的函数

六个参数:

参数1:src1,第一个原数组.
参数2:alpha,第一个数组元素权重 

参数3:src2第二个原数组
参数4:beta,第二个数组元素权重
参数5:gamma,图1与图2作和后添加的数值。

参数6:dst,输出图片

eg:

addWeighted(src1,0.5,src2,0.7,3,dst);

参数分别为:图1,图1的权重,图2,图2的权重,权重和添加的值为3,输出图片src

对比度调整:

注意:imshow里面的名称要统一,否则会出现错误

代码如下:

static void on_lightness(int b, void* userdata) {//回调函数,亮度调整
	Mat image = *((Mat*)userdata);
	Mat dst = Mat::zeros(image.size(), image.type());
	Mat m= Mat::zeros(image.size(), image.type());
	addWeighted(image,1.0,m,0,b,dst);
	imshow("亮度与对比度调整", dst);
}
static void on_contract(int b, void* userdata) {//回调函数,对比度调整
	Mat image = *((Mat*)userdata);
	Mat dst = Mat::zeros(image.size(), image.type());
	Mat m = Mat::zeros(image.size(), image.type());
	double contrast = b / 100.0;
	addWeighted(image, contrast, m, 0.0, b, dst);
	imshow("亮度与对比度调整", dst);
}
void quickdemo::tracking_bar_demo(Mat &image) {
	namedWindow("亮度与对比度调整", WINDOW_AUTOSIZE);
	int lightness = 50;
	int max_value = 100;//亮度调整
	int contrast_value = 100;
	createTrackbar("Value Bar", "亮度与对比度调整", &lightness, max_value, on_lightness,(void*)(&image));
	createTrackbar("Contrast Bar", "亮度与对比度调整", &lightness, max_value, on_contract, (void*)(&image));
	on_lightness(50, &image);
	on_contract(50, &image);
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值