OpenCV 4.0.0学习笔记 (二) 颜色空间转换、像素值访问与伪彩色

颜色空间转换 cvtColor

该函数的文档地址
函数原型:

void cv::cvtColor(InputArray src ,OutputArray dst,int code, int dstCn=0)
dst = cv2.cvtColor(src,code[,dst[,dstCn]])

dstCn :目标图像的通道数,默认值是0,表示由src和code决定

code表示转换标识,常见的BGR转灰度COLOR_BGR2GRAY

code转换码的取值

eg.

Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
imwrite("gray.png", gray);
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
cv2.imwrite('gray.png',gray)

创建新图:克隆复制与赋值

图像克隆、复制与 赋值

Mat m1 = src.clone(); //克隆原图像到新图
// 将原图src复制到新的图像m2
Mat m2;
src.copyTo(m2);
// 赋值
Mat m3 = src;
// 创建新图
Mat m4 = Mat::zeros(src.size(), src.type());
Mat m5 = Mat::zeros(Size(512, 512), CV_8UC3);
Mat m6 = Mat::ones(Size(512, 512), CV_8UC3);
m1 = np.copy(src)  #复制原图
# 赋值 切片访问像素
m2 = src
src[100:200,200:300,:] = 255  # m2同步更改
# np创建新的矩阵
m3 = np.zeros(src.shape, src.dtype)
m4 = np.zeros([512,512], np.uint8)
m5 = np.ones(shape=[512,512,3], dtype=np.uint8)
m5[:,:,0] = 255

像素值的访问

python版本的OpenCV,图像数据就是numpy.array,访问方式和数组一致。

c++版本的OpenCV,图像数据是Mat类,访问有十几种方式。参考了这篇博客https://blog.csdn.net/xiaowei_cqu/article/details/19839019

三种常用的是at模板函数的位置访问、ptr指针和data。此外迭代器等方式也比较高效。

#define CV_8U   0                   //对应uchar
#define CV_8S   1                   //对应char
#define CV_16U  2                   //对应ushort
#define CV_16S  3                   //对应short
#define CV_32S  4                   //对应int
#define CV_32F  5                   //对应float
#define CV_64F  6                   //对应double
/*   使用模板 成员函数Mat.at<>() */
// 单通道数据
Mat img1(1,256,CV_8U);// 1行256列的  二维 单通道数组
uchar data = img1.at<uchar>(0,10); // 访问img1的第一行第11个值 <>中的值由元素的类型决定,上面的定义是对应关系

Mat img2(1,256,CV_32FC3);//1行256的 二维3通道数组
float data = img2.at<cv::Vec3f>(0,10)[0]; //img2的第一行第11个位置 第一个通道,三通道的<>参数是vec3f这种,返回的是该位置的三个通道数据,因此需要[]索引访问三个不同的通道的值。 8UC3对应Vec3b

/* 使用ptr指针 */
int ROWS = 100; // height
int COLS = 200; // width
Mat img1(ROWS , COLS , CV_32FC1); 
for (int i=0; i<ROWS ; i++)   
{   
    float* pData1=img5.ptr<float>(i);  
    for (int j=0; j<COLS ; j++)   
    {   
        pData1[j] = 3.2f;   
    }   
}

/* Mat.data  */
Mat img(1,256,CV_8U);
uchar *p = img.data;
for(int i=0;i<256;i++){
    p[i] = 255 -i; //像素值翻转
}

伪彩色

将灰度图映射成伪彩色的图像,即将灰度图像的像素灰度值按照线性或者非线性函数映射到彩色空间,从而使呈现出彩色的显示效果。

applyColorMap

OpenCV提供的12种彩色图定义如下,函数是applyColorMap。

12种彩色映射

void cv::applyColorMap(InputArray src,OutputArray dst,InputArray userColor)	
dst	=  cv2.applyColorMap(src, colormap[, dst])
dst	=  cv2.applyColorMap(src, userColor[, dst])

该函数的输入src可以是灰度图,也可以是bgr三通道的图片。

import cv2
src = cv2.imread('alpha.png')
gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
dst	=  cv2.applyColorMap(src,cv2.COLORMAP_RAINBOW)
#ccv2.imshow("src",src)
cv2.imshow("gray",gray)
cv2.imshow("color",dst)
cv2.waitKey(0)

显示效果如下,伪彩色将灰度图的各个灰度值映射成彩色。

在这里插入图片描述

LUT查找表实现伪彩色

applycolormap只能使用12中固定的彩色映射,如要实现自定义的伪彩色需要使用cv::LUT,自定义一个查找表,然后将灰度值进行映射。比如定义的colormap,256灰度级的查找表table,将原始灰度值翻转,table[i] = 255 - i 将原始灰度值取反。

void cv :: LUT(InputArray 	src,InputArray 	lut,OutputArray DST )
DST	=cv2.LUT(src,lut [,dst]

自定义查找表,实现灰度值翻转的功能。

import cv2
import numpy as np
src = cv2.imread('123333.PNG')
gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
#dst=  cv2.applyColorMap(src,cv2.COLORMAP_RAINBOW)
#cv2.imshow("src",src)
table = np.zeros((1,256),gray.dtype) #对单通道灰度图作伪彩色,因此是1,256当然可以定义(3,256)对三通道的分量作不同的映射
print(table.shape)
for i in range(len(table[0])):
    table[0][i] = 255 - i # 将每个元素的原始灰度值翻转,这个操作若是有溢出就需要判断,255-i不会溢出
    '''if table[0][i] >255:
        table[0][i]=255
    if table[0][i]<0:
        table[0][i]=0'''
dst =cv2.LUT(gray,table)
#cv2.imshow("src",src)
cv2.imshow("gray",gray)
cv2.imshow("color",dst)
cv2.waitKey(0)

显示效果如下图
在这里插入图片描述
c++版本实现如下

Mat table(1, 256, CV_8U);
uchar *p = table.data;
for (int i = 0; i < 256; i++) {
    //img.at<float>(row,col)
    //table.at<uchar>(0,i) = 255 - i; //等价于p[i]访问像素值 
    p[i] = 255 - i;
}
Mat src = imread("123333.PNG");
Mat gray,dst;
cvtColor(src, gray, COLOR_BGR2GRAY); // 图像灰度化
LUT(gray, table, dst); // 将灰度化的图像使用LUT映射
imshow("color", dst);
imshow("Second", gray);
waitKey(0);
return 0;

在这里插入图片描述

对三通道彩色图做映射

#include <opencv2/imgcodecs.hpp>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int main()
{
	Mat table(1, 256, CV_8UC3);
	for (int i = 0; i < 256; i++) {
		//img.at<cv::Vec3b>(row,col) 对各个通道的灰度映射如下
		table.at<cv::Vec3b>(0,i)[1] =  255 - i; // B
		table.at<cv::Vec3b>(0, i)[0] = 255 - i;// *5 <0 ? 0: 255 - i*5; // G
		table.at<cv::Vec3b>(0, i)[2] = 255 - i;// *15<0 ? 0: 255 - i*15; //R
	
	}
	Mat src = imread("C:\\Users\\muyi\\Desktop\\pyproject\\123333.PNG");
	Mat dst;
	LUT(src, table, dst);
	imshow("src", src);
	imshow("color", dst);
	waitKey(0);
	return 0;
}

效果如下:
在这里插入图片描述

首次接触图像处理,通过次来记录自己的学习记录,以方便回忆。 //指针访问像素 void colorReduce(Mat& temImage, int div) { //行数 int rowNumber = temImage.rows; cout << "图像通道数:" << temImage.channels() << endl; //列数*通道数=每一行的元素个数 int colNumber = temImage.cols * temImage.channels(); for (int row = 0; row < rowNumber;row++) { uchar* data = temImage.ptr<uchar>(row); for (int col = 0; col < colNumber;col++) { data[col] = data[col] / div*div + div / 2; } } } //迭代器iterator操作像素 void iterColorReduce(Mat& temImage,int div) { Mat_<Vec3b>::iterator it = temImage.begin<Vec3b>(); Mat_<Vec3b>::iterator itend = temImage.end<Vec3b>(); //存取彩色图像的像素 while (it != itend) { //开始处理每个像素 (*it)[0] = (*it)[0] / div*div + div / 2; (*it)[1] = (*it)[1] / div*div + div / 2; (*it)[2] = (*it)[2] / div*div + div / 2; ++it; } } //动态地址计算像素 void atColorReduce(Mat& temImage, int div) { int rowNumber = temImage.rows; int colNumber = temImage.cols; //存取彩色图像 for (int row = 0; row < rowNumber; row++) { for (int col = 0; col < colNumber; col++) { //开始处理每个图像 //蓝色通道 temImage.at<Vec3b>(row, col)[0] = temImage.at<Vec3b>(row, col)[0] / div*div + div / 2; //绿色通道 temImage.at<Vec3b>(row, col)[1] = temImage.at<Vec3b>(row, col)[1] / div*div + div / 2; //红色通道 temImage.at<Vec3b>(row, col)[2] = temImage.at<Vec3b>(row, col)[2] / div*div + div / 2; } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值