博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
opencv学习笔记四(读写像素)
阅读量:3958 次
发布时间:2019-05-24

本文共 5141 字,大约阅读时间需要 17 分钟。

操作图像像素

图像操作

读写图像

  • imread 可以指定加载为灰度或者RGB图像
  • Imwrite 保存图像文件,类型由扩展名决定

读写像素

  • 读一个GRAY像素点的像素值(CV_8UC1)

    Scalar intensity = img.at(y, x);
    或者 Scalar intensity = img.at(Point(x, y));

  • 读一个RGB像素点的像素值

    Vec3f intensity = img.at(y, x);
    float blue = intensity.val[0];
    float green = intensity.val[1];
    float red = intensity.val[2];

修改像素值

  • 灰度图像

    img.at(y, x) = 128;

  • RGB三通道图像

    img.at(y,x)[0]=128; // blue
    img.at(y,x)[1]=128; // green
    img.at(y,x)[2]=128; // red

  • 空白图像赋值

    img = Scalar(0);

  • ROI选择

    Rect r(10, 10, 100, 100);
    Mat smallImg = img®;

Vec3b与Vec3F

  • Vec3b对应三通道的顺序是blue、green、red的uchar类型数据。
  • Vec3f对应三通道的float类型数据
    把CV_8UC1转换到CV32F1实现如下:
    src.convertTo(dst, CV_32F);

代码中函数简介

自定义函数

1. void grayInvert(Mat &gray);

功能:只对单通道灰度图像进行反差操作,:内含显示及存储功能
参数1:输入单通道灰度图像

2. void invertImage(Mat &src, Mat &dst);

功能:既可以对彩色图像进行反差,也可以对灰度图像进行反差(与opencv自带的一个函数bitwise_not功能相同,只是此处对图片像素值的操作不是二进制的操作)
参数1:输入一个图片(三通道或单通道都可)
参数2:输出dst反差图像

3. void imageToGray(Mat &src, Mat &dst);

功能:将rgb彩色图像变为单通道灰度图像(在其内转成灰度图像的方式较多,灰度图像有亮有暗)
参数1:输入一个三通道图像
参数2:输出单通道灰度图像

opencv自带函数

1. cvtColor(src, gray, CV_RGB2GRAY);

参数1:输入图像(此处应输入rgb三通道图像)
参数2:输出图像(此处输出单通道灰度图像)
参数3:此处使用CV_RGB2GRAY,表示将读入的rgb彩色图像变为gray灰度图像

2. bitwise_not(src, dst2);

功能:是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制 “非” 操作,~1 = 0,~0=1
参数1:输入一个图片(单通道或三通道都可)
参数2:输出像素值被二进制“非”过的图像

代码实现效果

1. 原始图像(为三通道彩色图像)

在这里插入图片描述
2. 原始彩色图像经由cvtColor(src, gray, CV_RGB2GRAY);所得的灰度图像(较暗)
在这里插入图片描述
3. 灰度图像经由grayInvert(gray);所得的反差图像
在这里插入图片描述
4. 原始彩色图像经由invertImage(src, dst);所得的反差图像(与bitwise_not结果相同)
在这里插入图片描述
5. 原始彩色图像经由bitwise_not(src, dst2);所得的反差图像
在这里插入图片描述
6. 原始彩色图像经由imageToGray(src, gray2);所得的灰度图像(较亮)
在这里插入图片描述

具体代码实现

#include 
#include
using namespace std;using namespace cv;//只对灰度图像进行反差并在窗口显示void grayInvert(Mat &gray);//输入单通道灰度图像//既可以对彩色图像进行反差,也可以对灰度图像进行反差void invertImage(Mat &src, Mat &dst);//输入一个图片(三通道或单通道都可),输出dst反差图像//自定义将rgb彩色图像变为单通道灰度图像(其内方法很多)void imageToGray(Mat &src, Mat &dst);//输入一个三通道图像,输出单通道灰度图像int main(){
Mat src; src = imread("1.jpg");//此处默认读进来BGR的图像(有三个通道的值) if (!src.data){
printf("could not load image...\n"); return -1; } //img.at
(y, x);获得单通道的图像才能去读 namedWindow("input image", CV_WINDOW_AUTOSIZE);//此处可以省略 imshow("input image", src); Mat gray; cvtColor(src, gray, CV_RGB2GRAY);//此时将rgb图像转变为灰度图像 namedWindow("cvtColor gray image", CV_WINDOW_AUTOSIZE);//此处可以省略 imshow("cvtColor gray image", gray); imwrite("cvtColor_gray.jpg", gray); grayInvert(gray);//只对灰度图像进行反差并在窗口显示 //调用自定义函数对图像进行反差 Mat dst;//定义dst反差图像 invertImage(src, dst); //既可以对彩色图像进行反差,也可以对灰度图像进行反差(对上面的grayInvert进一步优化) imshow("invertImage image", dst); //将输出的dst图像进行显示 imwrite("invertImage.jpg", dst); //调用系统自带的图像反差函数(与上方自定义反差功能相同,单通道、三通道都可) //此函数是进行位操作(与、或、非等)来对图像反差 Mat dst2; //定义dst2作为后面函数的输出 bitwise_not(src, dst2); imshow("bitwise_not image", dst2); imwrite("bitwise_not.jpg", dst2); //调用自定义rgb转灰度函数(灰度读图像可亮可暗) Mat gray2; imageToGray(src, gray2); imshow("imageToGray image", gray2); imwrite("imageToGray2.jpg", gray2); waitKey(0); return 0;}//只对灰度图像进行反差并在窗口显示void grayInvert(Mat &gray){
int height = gray.rows;//获取灰度图像的高度 int width = gray.cols;//获取灰度图像的宽度 //单通道灰度图像 for (int row = 0; row < height; row++){
for (int col = 0; col < width; col++){
int grayValue = gray.at
(row, col);//获取灰度图像的像素值 gray.at
(row, col) = (255 - grayValue); //修改gray图像本身的像素值,将其像素进行反差 } } imshow("gray invert", gray); //在3.0.0版本上,不用namewindows窗口,只imshow它就可以自动创建一个窗口展示 //imshow("gray image", gray); //如果找到前面有创建窗口,就不再自动创建,直接在之前创建的窗口显示 imwrite("gray_invert.jpg", gray);}//既可以对彩色图像进行反差,也可以对灰度图像进行反差void invertImage(Mat &src, Mat &dst){
//创建一个和src大小类型相同的背景图像,并将反差像素在此图像上显示 dst.create(src.size(), src.type()); int height = src.rows;//获取src图像的高度 int width = src.cols;//获取src图像的宽度 int nc = src.channels();//获取src图像的通道数 //直接遍历图像像素,并通过判断通道数来进行读取像素的操作(单通道和三通道读取像素操作不同) for (int row = 0; row < height; row++){
for (int col = 0; col < width; col++){
if (nc == 1){
//如果图像为单通道数进行下列操作 int grayValue = src.at
(row, col); //获取单通道图像的像素值 dst.at
(row, col) = (255 - grayValue); //修改单通道图像本身的像素值,将其像素进行反差 } else if (nc == 3){ //如果图像为三通道 int b = src.at
(row, col)[0]; //获取r通道的像素值 int g = src.at
(row, col)[1]; //获取g通道的像素值 int r = src.at
(row, col)[2]; //获取b通道的像素值 //将各个通道的反差像素在dst图像上显示 dst.at
(row, col)[0] = 255 - b; //我们可以更改一些像素值,会得到其他效果如将(255-r)改为0等像素值 dst.at
(row, col)[1] = 255 - g; dst.at
(row, col)[2] = 255 - r; } } } //imshow("dst invert", dst);}//自定义将rgb彩色图像变为单通道灰度图像(其内方法很多)void imageToGray(Mat &src, Mat &dst){ //创建一个和src大小相同,但类型为单通道的背景图像 dst.create(src.size(), CV_8UC1); int height = src.rows;//获取src图像的高度 int width = src.cols;//获取src图像的宽度 int nc = src.channels();//获取src图像的通道数 //直接遍历图像像素,并通过判断通道数来进行读取像素的操作(单通道和三通道读取像素操作不同) for (int row = 0; row < height; row++){ for (int col = 0; col < width; col++){ if (nc == 1){ //如果图像为单通道数进行下列操作 cout << "此为单通道图像,无需再次灰度化" << endl; } else if (nc == 3){ //如果图像为三通道 int b = src.at
(row, col)[0]; //获取r通道的像素值 int g = src.at
(row, col)[1]; //获取g通道的像素值 int r = src.at
(row, col)[2]; //获取b通道的像素值 //通过获取的bgb各通道的像素值进行灰度化操作(做灰度的方法很多) //dst.at
(row, col) = min(b, min(g, r));//取rgb通道中的最小值赋值给单通道像素(此处的灰度图像显示会比较暗) dst.at
(row, col) = max(b, max(g, r));//取rgb通道中的最大值赋值给单通道像素(此处的灰度图像显示会比较亮) } } } //imshow("imageToGray", dst);}

转载地址:http://szozi.baihongyu.com/

你可能感兴趣的文章
理解套接字recv(),send()
查看>>
发一个C++写的跨平台的BlockingQueue
查看>>
Linux TCP/IP协议栈剖析【体系结构篇】
查看>>
游戏开发中预防内存泄露的一些措施
查看>>
以前的文章全部移除了。
查看>>
几首歌
查看>>
蝴蝶泉边
查看>>
编码转换
查看>>
freerice
查看>>
Does your mother know
查看>>
《写出质量好软件的75条体会》暨答案ZT [转自monkyy的blog]
查看>>
关于详细设计
查看>>
POJ2838,Sliding Window(单调队列)
查看>>
牛客练习赛50,B tokitsukaze and Hash Table(STL+输入输出挂)
查看>>
POJ3728,The merchant(倍增LCA+分治)
查看>>
2019 ICPC Malaysia National,E. Optimal Slots(01背包变形)
查看>>
洛谷P1638 逛画展(双向队列)
查看>>
牛客练习赛51,D(二分图匹配)
查看>>
POJ2892,Tunnel Warfare(线段树维护连续区间)
查看>>
POJ3468,A Simple Problem with Integers(线段树-区间查询-区间更新)
查看>>