opencv学习记录——(5)图像像素的操作

1、先补充几点opencv的相关知识点

1.1  通过Scalar来设置颜色

Scalar(b1, b2, b3, b4),前面的三个参数是依次设置BGR的,和RGB相反,第四个参数设置图片的透明度。 如果不需要 设置透明度,则可以把第四个参数去掉。

1.2  Vec3b类型的使用

Vec3b就是一个uchar类型的数组,长度为 3

1.2.1  对Vec3b的定义

Vec3b color;  //变量 color 是一个长度为 3 的 uchar 数组,用于描述 RGB 颜色

//在 OpenCV 中,颜色为 BGR,而不是 RGB
color[0] = 255;    // 0 是 B 通道,该句修改 B 通道数据
color[1] = 255;    // 1 是 G 通道,该句修改 G 通道数据
color[2] = 255;    // 2 是 R 通道,该句修改 R 通道数据

 1.2.2 使用vec3b读取像素

由于在OpenCV中,使用imread读取到的Mat图像数据,都是用uchar类型的数据存储,对于RGB三通道的图像,每个点的数据都是一个Vec3b类型的数据。

使用at定位方法如下:

Mat mat = imread("test.jpg");

//(row, col)即所需要定位点的坐标
mat.at<Vec3b>(row, col)[0] = 255;  //修改点 (row, col) 的 B 通道数据
mat.at<Vec3b>(row, col)[1] = 255;  //修改点 (row, col) 的 G 通道数据
mat.at<Vec3b>(row, col)[2] = 255;  //修改点 (row, col) 的 R 通道数据

再如下例,返回值为<>中的类型:

Mat mat;

mat.at<uchar>(row, col);    //单通道,返回一个 uchar 类型值
mat.at<Vec3b>(row, col);    //三通道,返回 <Vec3b>,即返回一个 uchar 数组,长度为 3
mat.at<Vec4b>(row, col);    //四通道

需要注意的是,上例中返回的都是uchar类型,直接使用cout输出为字符格式,需要强制转换为int类型之后输出:

Vec3b bgr = frame.at<Vec3b>(i, j);

printf("b = %d, g = %d, r = %d\n", bgr[0], bgr[1], bgr[2]);
//或
cout << (int)bgr[0] << ", " << (int)bgr.val[1] << ", " << (int)bgr.val[2] << endl;

以上转载自:(79条消息) 【OpenCV】关于Vec3b类型的含义与使用_ReturnZC的博客-CSDN博客_opencv vec3b

2 、 图像像素的操作

本节主要实现对图像的各个像素点实现加减乘除的操作,可以起到改变图像亮度的作用,本节还会介绍并使用常用的saturate_cast函数,防止数值溢出。

2.1 补充saturate_cast函数

在图像处理方面,无论是加、减、乘、除,都会超出一个像素灰度值的范围(0~255),saturate_cast函数的作用即是:当运算完之后,结果为负,则转为0,结果超出255,则为255。

使用方法:

使用前:

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

使用后:

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

 2.2 加、减、乘、除 在代码中的表示方式

(1) 加 add(image, m, dst) ,其中 image 为输入的原图像,m为要对image进行操作的图像

dst为操作结束后的输出图像。

(2)减法:subtract()

(3)惩罚multiply()

 2.3 对图像像素进行操作代码实现

void QuickDemo::operators_demo(Mat &image)
{
Mat dst = Mat::zeros(image.size(), image.type());//把dst对象初始化,设置成image的大小和形式
	Mat m = Mat::zeros(image.size(), image.type());//把m对象初始化,设置成image的大小和形式
	dst = image - Scalar(50, 50, 50); //对image对Scalar做减法,可以降低图像亮度
	m = Scalar(50, 50, 50); 
	multiply(image,m,dst);//乘法操作 api
	imshow("乘法操作", dst);
	add(image, m, dst);//加法操作 api
	imshow("加法操作", dst);
	subtract(image, m, dst);//减法操作 api
	imshow("减法操作", dst);
	divide(image, m, dst);//除法操作 api
	namedWindow("加法操作", WINDOW_FREERATIO);
	imshow("加法操作", dst);
	//加法操作底层  其原理就是将三个通道中的每个像素点做加减乘除操作,从而实现改变图像的亮度
	int dims = image.channels();
	int h = image.rows;
	int w = image.cols;
	for (int row = 0; row < h; row++)
	{
		for (int col = 0; col < w; col++)
		{
				Vec3b p1 = image.at<Vec3b>(row, col); //opencv特定的类型,获取三维颜色,3个值
				Vec3b p2 = m.at<Vec3b>(row, col);
				dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(p1[0]	+ p2[0]);//saturate_cast用来防爆,小于0就是0,大于255就是255
				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]);//对彩色图像读取它的像素值,并且对像素值进行改写。
		}
	}
	imshow("加法操作", dst);
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Opencv中的分水岭算法(watershed algorithm)是一种自动图像分割算法,常用于分离图像中的前景和背景。下面是使用Opencv中的分水岭算法进行图像分割的步骤: 1. 读入图像并进行预处理,如去噪、灰度化等。 2. 对图像进行二值化处理,得到前景和背景的二值图像。 3. 对二值图像进行距离变换(distance transform),得到每个像素离最近的背景像素的距离。 4. 对距离变换后的图像进行阈值处理,得到图像的分水岭标记(watershed markers)。 5. 对分水岭标记进行修正,确保标记不会重叠或出现空洞。 6. 对分水岭标记应用分水岭算法,得到分割后的图像。 下面是使用Opencv实现分水岭算法的示例代码: ```python import cv2 import numpy as np # 读取图像并进行预处理 img = cv2.imread('input.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # 进行距离变换 dist_transform = cv2.distanceTransform(thresh,cv2.DIST_L2,5) ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0) # 获取分水岭标记 sure_fg = np.uint8(sure_fg) unknown = cv2.subtract(thresh,sure_fg) ret, markers = cv2.connectedComponents(sure_fg) markers = markers+1 markers[unknown==255] = 0 # 修正分水岭标记 markers = cv2.watershed(img,markers) img[markers == -1] = [255,0,0] # 显示分割结果 cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这段代码中,我们首先读入一张图像并进行预处理,然后进行距离变换,得到每个像素到最近的背景像素的距离。接着使用阈值处理得到分水岭标记,修正分水岭标记并应用分水岭算法,最后显示分割结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值