TensorRT(回忆图像中的像素访问)

此文章只作为复习所用,勿喷。

Mat在内存中存储形式

  灰度图的存储形式

    

 

  RGB的存储形式

  

一般情况下,Mat是连续存储的,按行连接。可以通过isContinuous()函数,判断矩阵是否连续存储,若连续返回true。

参考:https://www.cnblogs.com/kuotian/p/6389260.html

    刚开始接触到OpenCV,本身是想学借助OpenCV的库来进行图像处理学习的,后来发现OpenCV将所有的东西都集成起来了,对于打算学习图像处理来说这样反而不是什么好事;

    在我看来,图像处理基本基于对像素值得处理,那么我们尽可能的用数组来存储像素值,对于OpenCV来说不便于按照我们的做法来对图片进行处理。但是OpenCV给我们集成了cv::Mat::at这样一个结构,用于读取图片的像素值,那么我们就可以使用它来将像素值存储在数组中了。

    image.at<Vec3b>(row, col)[i]可以读取到图片中的像素值,row为行、col为列、i为RGB的第几通道。

for (int row = 0; row < image.rows; row++)      //行
    {
        for (int col = 0; col < image.cols; col++)  //列
        {
            for (int i = 0; i < 3; i++)
            {
                str[row * 400 * 3 + col * 3 + i] = image.at<Vec3b>(row, col)[i];
            }
        }
    }
    这样我们就可以将image图片中的像素值保存到str数组中,我们采用的是三通道RGB图片,在数组中的存储顺序是B,G,R。

    但是这里有个缺陷就是我们需要首先数组的长度,那么就意味着对应的图片长宽是固定的。

    对于之后的图像显示,我仍然使用了能被openCV处理的Mat格式图像数据,就是对指向图像的指针生成Mat格式的图像数据。

int fnCameraCheckA(unsigned char* imageData, int width, int height, int *result1)
{
    Mat img(height, width, CV_8UC3, imageData);  //CV_8UC3:8位无符号的三通道---RGB彩色图像
    if (!img.data)
    {
        printf(" No image data \n ");
        return -1;
    }
    imshow("传递过来的图像", img);
    *result1 = 1;
    return 1;
}
    这样我们就可以随意的对图片进行处理,并借助OpenCV强大的底层库进行其他操作。

#include <cv.h>  
#include <highgui.h>  
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cstring>
 
using namespace cv;
 
int fnCameraCheckA(unsigned char* imageData, int width, int height, int * result);
 
int main(int argc, char** argv)
{
    const char* imageName = "test_2.bmp";
    Mat image;
    image = imread(imageName);     //读图片
 
    char str[400 * 400 * 3];
    for (int row = 0; row < image.rows; row++)      //行
    {
        for (int col = 0; col < image.cols; col++)  //列
        {
            for (int i = 0; i < 3; i++)
            {
                str[row * 400 * 3 + col * 3 + i] = image.at<Vec3b>(row, col)[i];
            }
        }
    }
    char* imgData = str;
    imshow("原图", image);
 
    int width, height;
    int a = -1;
    int *result1 = &a;   //判断是否传递成功
    width = image.cols;  // 列数
    height = image.rows; // 行数
 
 
    //  利用传递过来的图像指针和行列参数,生成能被openCV处理的Mat格式图像数据
    fnCameraCheckA((unsigned char*)imgData, width, height, result1);
    if (*result1 == 1)
    {
        printf("图像传递successful!!");
    }
 
    waitKey(0);
    return 0;
}
 
int fnCameraCheckA(unsigned char* imageData, int width, int height, int *result1)
{
    Mat img(height, width, CV_8UC3, imageData);  //CV_8UC3:8位无符号的三通道---RGB彩色图像
    if (!img.data)
    {
        printf(" No image data \n ");
        return -1;
    }
    imshow("传递过来的图像", img);
    *result1 = 1;
    return 1;
}
 

1. 彩色图像转灰度图像

RGB转灰度,通常会使用下面的一个心理学公式:(Matlab和OpenCV中使用的也是该公式)

Gray = 0.2989*R + 0.5870*G + 0.1140*B

实现代码如下

2. 计算速度优化

抛却指令优化不谈,优化转化速度的最直接方法就是将浮点运算转化为整数运算:

比如我们可以将上式转化为:

Gray = (2989*R + 5870*G + 1140*B)/ 10000,

但是上面的除法还是不够快,我们完全可以使用移位操作来代替:

Gray = (4898*R + 9618*G + 1868*B)>> 14

此外,对大部分计算机视觉应用来说,图像的精度问题不是一个特别敏感的问题,因此我们可以通过降低精度来进一步减少计算量:(我通常使用8位精度)

Gray = (76*R + 150*G + 30*B)>> 8

对应的C++ 程序也比较简单:

 

转载地址:https://blog.csdn.net/kuweicai/article/details/73414138

用数组方式求三通道图像转灰度图像
RGB转换成灰度图像的一个常用公式是:
Gray = R*0.299 + G*0.587 + B*0.114
//灰度转换函数*******
//第一个参数image输入的彩色RGB图像的引用;
//第二个参数imageGray是转换后输出的灰度图像的引用;
//*******************************************************

#include <opencv2\opencv.hpp>
using namespace cv;
void ConvertRGB2GRAY(const Mat &image, Mat &imageGray);

int main()
{
    Mat src = imread("catGuitar.jpg");
    Mat grayImage;
    ConvertRGB2GRAY(src, grayImage);
    imshow("gray image", grayImage);
    imwrite("grayimage.jpg", grayImage);
    waitKey(0);
    return 0;
}

void ConvertRGB2GRAY(const Mat &image, Mat &imageGray)
{
    if (!image.data || image.channels() != 3)
    {
        return;
    }
    //创建一张单通道的灰度图像
    imageGray = Mat::zeros(image.size(), CV_8UC1);
    //取出存储图像像素的数组的指针
    uchar *pointImage = image.data;
    uchar *pointImageGray = imageGray.data;
    //取出图像每行所占的字节数
    size_t stepImage = image.step;
    size_t stepImageGray = imageGray.step;
    for (int i = 0; i < imageGray.rows; i++)
    {
        for (int j = 0; j < imageGray.cols; j++)
        {
            pointImageGray[i*stepImageGray + j] =
                (uchar)(0.114*pointImage[i*stepImage + 3 * j] +
                    0.587*pointImage[i*stepImage + 3 * j + 1] +
                    0.299*pointImage[i*stepImage + 3 * j + 2]);
        }
    }
}
--------------------- 
作者:孤岛violet 
来源:CSDN 
原文:https://blog.csdn.net/fly_wt/article/details/86432886 
原始LBP纹理特征提取方法介绍以及代码实现
https://blog.csdn.net/qq_22562949/article/details/45966009
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值