// LoadBmp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <direct.h>
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
bool ReadAbsolutePathFile(const char* pAbsolutePath, const char* pMode, unsigned char* pData/*out*/, long& nLen)
{
if (!pAbsolutePath || !pMode || !pData) {
return false;
}
FILE* pFile = fopen(pAbsolutePath, pMode);
if (pFile) {
fseek(pFile, 0, SEEK_END);
nLen = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
nLen = fread(pData, 1, nLen, pFile);
fclose(pFile);
return true;
}
return false;
}
bool WriteFile(const char* pFileName, const char* pMode, unsigned char* pData, long nLen)
{
if (!pFileName || !pMode || !pData) {
return false;
}
if (nLen <= 0) {
return false;
}
char cPath[2048] = { 0 };
_getcwd(cPath, 2048);
sprintf(cPath + strlen(cPath), "/%s", pFileName);
FILE* pFile = fopen(cPath, pMode);
if (pFile) {
long nWrite = fwrite(pData, 1, nLen, pFile);
fclose(pFile);
if (nWrite > 0) {
return true;
}
}
return false;
}
int Nv12DrawRect(char* pNv12Data, int nImageWidth, int nImageHeight, int nLeft, int nTop, int nRectWidth, int nRectHeight, int R, int G, int B)
{
/* RGB convert YUV */
/*int Y = 0.299 * R + 0.587 * G + 0.114 * B;
int U = -0.1687 * R + 0.3313 * G + 0.5 * B + 128;
int V = 0.5 * R - 0.4187 * G - 0.0813 * B + 128;*/
int Y = R;
int U = G;
int V = B;
if (nLeft < 0) {
nLeft = 0;
}
if (nTop < 0) {
nTop = 0;
}
//
int nVaildWidth = 0;
if (nLeft + nRectWidth >= nImageWidth) {
nVaildWidth = nImageWidth - nLeft - 2;//0到nImageWidth - 1行,所以减去1,还有一个像素的边框大小
}
else {
nVaildWidth = nLeft + nRectWidth;
}
//
int nValidHeight = 0;
if (nTop + nRectHeight >= nImageHeight) {
nValidHeight = nImageHeight - nTop - 2;//0到nImageHeight - 1行,所以减去1,还有一个像素的边框大小
}
else {
nValidHeight = nTop + nRectHeight;
}
//上横线
for (int i = nLeft; i < nVaildWidth; i++) {
pNv12Data[nTop * nImageWidth + i] = Y;
pNv12Data[nImageWidth * nImageHeight + nTop * nImageWidth / 2 + i] = U;
pNv12Data[nImageWidth * nImageHeight + nTop * nImageWidth / 2 + i + 1] = V;
}
//下横线
for (int i = nLeft; i < nVaildWidth; i++) {
pNv12Data[nValidHeight * nImageWidth + i] = 0;
}
for (int i = nLeft; i < nVaildWidth; i++) {
pNv12Data[nImageWidth * nImageHeight + nValidHeight * nImageWidth / 2 + i] = U;
pNv12Data[nImageWidth * nImageHeight + nValidHeight * nImageWidth / 2 + i + 1] = V;
}
//左竖线
for (int i = nTop; i < nValidHeight; i++) {
pNv12Data[i * nImageWidth + nLeft] = Y;
}
for (int i = nTop / 2; i < nValidHeight / 2; i++) {
pNv12Data[nImageWidth * nImageHeight + i * nImageWidth + nLeft] = U;
pNv12Data[nImageWidth * nImageHeight + i * nImageWidth + nLeft + 1] = V;
}
//右竖线
for (int i = nTop; i < nValidHeight; i++) {
pNv12Data[i * nImageWidth + nLeft] = Y;
}
for (int i = nTop / 2; i < nValidHeight / 2 + 1/*这里加1的作用是多画一行*/; i++) {
pNv12Data[nImageWidth * nImageHeight + i * nImageWidth + nVaildWidth] = U;
pNv12Data[nImageWidth * nImageHeight + i * nImageWidth + nVaildWidth + 1] = V;
}
return 0;
}
int main()
{
unsigned char* pData = new unsigned char[1920 * 1080 * 3];
int nWidth = 640;
int nHeight = 360;
cv::Mat stNv12(nHeight * 1.5, nWidth, CV_8UC1);
long nLen = 0;
ReadAbsolutePathFile("D:\\ImageToNv12\\11.yuv", "rb+", pData, nLen);
memcpy(stNv12.data, pData, nLen);
Nv12DrawRect((char*)stNv12.data, 640, 360, -10, -10, 700, 450, 255, 0, 0);
cv::Mat stMatImage = cv::Mat(360, 640, CV_8UC3);
cv::cvtColor(stNv12, stMatImage, COLOR_YUV2BGR_NV12);
cv::imwrite("11111.jpg", stMatImage);
delete[] pData;
return 0;
}
Nv12图像:
绘制一个边界在图像外的图像: