C++图像处理学习一(图像YUV转RGB,图像文件遍历,图像内存拷贝)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiao__run/article/details/82391402

C++ 是一门古老而复杂的语言,绝不是一门可以速成的语言,学习它需要有意识的刻意练习和长时间的持续不断的磨练。而大多数人不太能耐得住寂寞,喜欢速成,所以像《 21 天学通 C++ 》这种书就比较受欢迎,卖得很好。通常那些干了一两年就说自己熟悉(甚至精通) C++ 的程序员只能算是轻浮的。(貌似说的就是我自己,哈哈)
Linux 之父 Linus 就曾说:“ C++ 是一门很恐怖的语言,而比它更恐怖的是很多不合格的程序员在使用着它”。
所以,要学习 C++ 并打算将其作为自己的首选编程语言,就要做好吃十年寒窗苦的准备,要耐得住寂寞,经得起考验,最终才能举重若轻,有所成就。
也正因为此,很多人不大愿意学习 C++,还会找一些理由,比如 C++ 没落了、应用前景不广泛了作为理由。其实 C++ 仍然在不断发展,生命力依然旺盛,有大量的行业和不计其数的应用正在源源不断地引入 C++ 语言,它的前景依然看好。(最近的项目让我体会到了C++无处不在)
由此,小编决定重拾C++,刻苦钻研,今天正好碰到了一个图像处理知识:
大体任务需要知识点:遍历文件夹下所有图片,就是将YUV图像转换成RGB,opencv又无此格式转换函数,如何将图像拷贝进buffer, 从buffer中读取图像

1、从文件夹中读取图像进入文件进入buffer

// read a file into memory
#include <iostream>     // std::cout
#include <fstream>      // std::ifstream

int main () {

  std::ifstream is ("test.txt", std::ifstream::binary);
  if (is) {
    // get length of file:
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);

    char * buffer = new char [length];

    std::cout << "Reading " << length << " characters... ";
    // read data as a block:
    is.read (buffer,length);

    if (is)
      std::cout << "all characters read successfully.";
    else
      std::cout << "error: only " << is.gcount() << " could be read";
    is.close();

    // ...buffer contains the entire file...

    delete[] buffer;
  }
  return 0;
}

以此为例,将图像拷贝进buffer

输入图像的文件 String str_Route, 
输出图像的动态内存unsigned char *psrc_image

int ReadFileYUV(String str_Route, unsigned char *psrc_image) {

    std::ifstream is(str_Route, std::ifstream::binary);
    if (is) {
        // get length of file:
        is.seekg(0, is.end);
        int length = is.tellg();
        is.seekg(0, is.beg);

        char * buffer = new char[length];

        std::cout << "Reading " << length << " characters... ";
        // read data as a block:
        is.read(buffer, length);

        if (is)
            std::cout << "all characters read successfully.";
        else
            std::cout << "error: only " << is.gcount() << " could be read";
        is.close();

        // ...buffer contains the entire file...

        memcpy(psrc_image, buffer, length);

        delete[] buffer;
    }
    return 0;
}

遍历文件夹下图片(opencv glob函数)

vector <String> read_images_in_folder(cv::String pattern)
{
    vector<cv::String> fn;
    glob(pattern, fn, false);

    vector<String> imagesname;
    size_t count = fn.size(); //number of png files in images folder
    for (size_t i = 0; i < count; i++)
    {
        imagesname.push_back(fn[i]);

        //cout << fn[i]<<endl;
    }
    return imagesname;
}

3、调用代码

src = (unsigned char *)malloc(2560 * 720);
ReadFileYUV(filename[i], src);

YUV转RGB代码

#include "opencv2/opencv.hpp"
#include <iostream>
#include <vector>
#include <windows.h>

using namespace cv;
using namespace std;
string num2str(int i)
{
    stringstream ss;
    ss << i;
    return ss.str();
}
#define RANGE_INT(iVal, iMin, iMax)                     ( ( ( iVal ) > ( iMin ) ) ? ( ( ( iVal ) <= ( iMax ) ) ? ( iVal ) : ( iMax ) ) : ( iMin ) )  
#define ROUND_SHR_POSITIVE(Dividend, iShiftRightCount)  ( ( ( Dividend ) & ( 1 << ( ( iShiftRightCount ) - 1 ) ) ) ? ( ( Dividend ) >> ( iShiftRightCount ) ) + 1 : ( ( Dividend ) >> ( iShiftRightCount ) ) )  
#define ROUND_SHR_NEGATIVE(Dividend, iShiftRightCount)  ( -( ( ( -( Dividend ) ) & ( 1 << ( ( iShiftRightCount ) - 1 ) ) ) ? ( ( -( Dividend ) ) >> ( iShiftRightCount ) ) + 1 : ( ( -( Dividend ) ) >> ( iShiftRightCount ) ) ) )  
#define ROUND_SHR(Dividend, iShiftRightCount)           ( ( ( Dividend ) >= 0 ) ? ROUND_SHR_POSITIVE( Dividend, iShiftRightCount ) : ROUND_SHR_NEGATIVE( Dividend, iShiftRightCount ) )  

vector <String> read_images_in_folder(cv::String pattern)
{
    vector<cv::String> fn;
    glob(pattern, fn, false);

    vector<String> imagesname;
    size_t count = fn.size(); //number of png files in images folder
    for (size_t i = 0; i < count; i++)
    {
        imagesname.push_back(fn[i]);

        //cout << fn[i]<<endl;
    }
    return imagesname;
}

void YCbCr2RGB_Pixel(unsigned char Y, unsigned char Cb, unsigned char Cr, unsigned char* R, unsigned char* G, unsigned char* B)
{
    int iTmpR = 0;
    int iTmpG = 0;
    int iTmpB = 0;

    iTmpR = (((int)Y) << 14) + 22970 * (((int)Y) - 128);
    iTmpG = (((int)Y) << 14) - 5638 * (((int)Cb) - 128) - 11700 * (((int)Cr) - 128);
    iTmpB = (((int)Y) << 14) + 29032 * (((int)Cb) - 128);

    iTmpR = ROUND_SHR(iTmpR, 14);
    iTmpG = ROUND_SHR(iTmpG, 14);
    iTmpB = ROUND_SHR(iTmpB, 14);

    *R = (unsigned char)RANGE_INT(iTmpR, 0, 255);
    *G = (unsigned char)RANGE_INT(iTmpG, 0, 255);
    *B = (unsigned char)RANGE_INT(iTmpB, 0, 255); 

        //printf("--%d %d %d %d %d %d--\n", iTmpR, iTmpG, iTmpB, *R, *G, *B);
}

void YCbCr2RGB(unsigned char* pdst, unsigned char* psrc, int width, int height)
{
    unsigned char *pY1 = 0;
    unsigned char *pY2 = 0;
    unsigned char *pU = 0;
    unsigned char *pV = 0;
    unsigned char *pR = 0;
    unsigned char *pG = 0;
    unsigned char *pB = 0;

    /*  UYVY  */
    pU = psrc;
    pY1 = psrc + 1;
    pV = psrc + 2;
    pY2 = psrc + 3;

    pR = pdst;
    pG = pdst + 1;
    pB = pdst + 2;

    int loopcnt = width * height / 2; //write 2 pixels each opt

    for (int i = 0; i < loopcnt; i++) 
    {

        YCbCr2RGB_Pixel(*pY1, *pU, *pV, pR, pG, pB);
        pR += 3;
        pB += 3;
        pG += 3;

        YCbCr2RGB_Pixel(*pY2, *pU, *pV, pR, pG, pB);
        pR += 3;
        pB += 3;
        pG += 3;

        pY1 += 4;
        pY2 += 4;
        pU += 4;
        pV += 4;
    }
}

int ReadFileYUV(String str_Route, unsigned char *psrc_image) {

    std::ifstream is(str_Route, std::ifstream::binary);
    if (is) {
        // get length of file:
        is.seekg(0, is.end);
        int length = is.tellg();
        is.seekg(0, is.beg);

        char * buffer = new char[length];

        std::cout << "Reading " << length << " characters... ";
        // read data as a block:
        is.read(buffer, length);

        if (is)
            std::cout << "all characters read successfully.";
        else
            std::cout << "error: only " << is.gcount() << " could be read";
        is.close();

        // ...buffer contains the entire file...

        memcpy(psrc_image, buffer, length);

        delete[] buffer;
    }
    return 0;
}

int main()
{
    string strname,strname1;
    string pathname = "F:\\BaiduNetdiskDownload\\环视\\img_svm\\*.yuv";
    //for (size_t i = 0; i < 100; i++)
    //{
    //  cout << "hello" << endl;

    //}
    Mat dst(720, 1280, CV_8UC3);
    unsigned char *src;
    src = (unsigned char *)malloc(2560 * 720);

    vector<String> filename(read_images_in_folder(pathname));

    std::fstream fs;

    for (int i = 0; i < filename.size(); i++)
    {
        cout << "["<<i+1<< "] = " << filename[i] << endl;

        ReadFileYUV(filename[i], src);

        YCbCr2RGB(dst.data, src, 1280,720);
        imread(filename[i]);
        waitKey(3000);
        strname = num2str(i);
        strname1 = strname + ".jpg";
        cv::imwrite(strname1,dst);
    }

    free(src);
    src = NULL;
    fs.close();
    return 0;

}

猜你喜欢

转载自blog.csdn.net/xiao__run/article/details/82391402
今日推荐