OpenCV笔记(二)cvtColor与伪彩色、图像复制与像素访问

颜色空间转换 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)

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

image.png

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;
c++实现

对三通道彩色图做映射

#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; // 还可以每个通道映射方式不一样
        table.at<cv::Vec3b>(0, i)[0] = 255 - i;// *5 <0 ? 0: 255 - i*5; 
        table.at<cv::Vec3b>(0, i)[2] = 255 - i;// *15<0 ? 0: 255 - i*15; 
    
    }
    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;
}

效果如下:


映射效果
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容