zoukankan      html  css  js  c++  java
  • 关于QImage提取单色通道方法(vector)

      转载请标明处:

      作者:微微苏荷

      本文地址:关于QImage提取单色通道方法(vector)


      近日,用QT和mxnet结合做一个图像识别的demo。遇到需要把图片从QImage转为vector单色分离的格式的要求,用来识别时输入。
    经实践,找到3种方法,分享给大家:
    需要注意的是,QImage的存储顺序是 BGRA(opencv也是这样反着的),不是正常口述RGBA.

    另:mx_float  == float
    一.

    int image_size = width * height * channels; //图像的宽/高/通道数(除去了A通道)
    std::vector<mx_float> image_data = std::vector<mx_float>(image_size);
    mx_float* ptr_image_r = image_data.data();
    const uchar* pData= image.constBits(); // 获取图像原始数据
    
    mx_float* ptr_image_g = image_data.data() + image_size / 3;
    mx_float* ptr_image_b = image_data.data() + image_size / 3 * 2;
    for (int i = 0; i < height; i++){
        int lineNum_32 = i * width * 4;
        for (int k = 0; k < width; k++){
            if(1 < IMAGE_CHANNELS){
            // 乘以4的原因是QImage是四个通道存储的,BGRA,所以每个像素都占有4个字节。
               *ptr_image_r++ = static_cast<mx_float> (pData[lineNum_32 + k * 4 + 2]) ;
               *ptr_image_g++ = static_cast<mx_float> (pData[lineNum_32 + k * 4 + 1]);
            }
            *ptr_image_b++ = static_cast<mx_float> (pData[lineNum_32 + k * 4 ]) ;
         }    
    }        
    

     二.利用image.scanLine(),获取每行扫描线的首地址

    int image_size = width * height * channels; //图像的宽/高/通道数(除去了A通道)
    std::vector<mx_float> image_data = std::vector<mx_float>(image_size);
    mx_float* ptr_image_r = image_data.data();
    const uchar* pData= image.constBits(); // 获取图像原始数据
    
    mx_float* ptr_image_g = image_data.data() + image_size / 3;
    mx_float* ptr_image_b = image_data.data() + image_size / 3 * 2;
    for (int i = 0; i < height; i++){
        uchar *imageScanLine = image.scanLine(i);
        for (int k = 0; k < width; k++){
            if(1 < IMAGE_CHANNELS){
            // 乘以4的原因是QImage是四个通道存储的,BGRA,所以每个像素都占有4个字节。
               *ptr_image_r++ = static_cast<mx_float>(
                                imageScanLine[k * 4 + 2]) ;
               *ptr_image_g++ = static_cast<mx_float>(
                                imageScanLine[k * 4 + 1]) ;
                    
            }
            *ptr_image_b++ = static_cast<mx_float>(
                                imageScanLine[k * 4]) ;
         }    
    }        
    

    三.最可靠最简洁的方法.但是可能性能比上两个稍微差些(没有评估),因为他每个像素都要从QImage获取一次,不确定会不会比一次获取完和一次获取一行有性能之差,但个人感觉不会,因为QImage也是在内存中,不存在文件IO。但是他很简单,不需要考虑图片的位深和存储顺序/大端小端等问题。

    int image_size = width * height * channels; //图像的宽/高/通道数(除去了A通道)
    std::vector<mx_float> image_data = std::vector<mx_float>(image_size);
    mx_float* ptr_image_r = image_data.data();
    const uchar* pData= image.constBits(); // 获取图像原始数据
    
    mx_float* ptr_image_g = image_data.data() + image_size / 3;
    mx_float* ptr_image_b = image_data.data() + image_size / 3 * 2;
    for (int i = 0; i < height; i++){
        uchar *imageScanLine = image.scanLine(i);
        for (int k = 0; k < width; k++){
                // 没有做兼容单通道
          QRgb bits = image.pixel(i, k);
           *ptr_image_r++ = static_cast<mx_float>(qRed(bits)) ;
           *ptr_image_g++ = static_cast<mx_float>(qGreen(bits));
           *ptr_image_b++ = static_cast<mx_float>(qBlue(bits)) ;
        }    
    }                
    

      

  • 相关阅读:
    Dockerfile构建
    ElasticSearch学习之集成客户端
    区块链学习之Hyperledger Fabric开发环境搭建(Go+Docker+Fabric)
    区块链学习之什么是区块链(基础入门)
    python学习之多版本管理及Python安装/卸载遇到的坑(MAC版)
    ElasticSearch学习之基本原理概述
    ElasticSearch学习之基本概念及单机/集群部署
    Kafka学习之Kafka选举机制简述
    Kafka学习之内核原理剖析
    通过idea将java项目发布到harbor仓库
  • 原文地址:https://www.cnblogs.com/weiweisuhe/p/6004323.html
Copyright © 2011-2022 走看看