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

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.c_str(), 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;

}
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页