1.python版本
def bgr2nv21(input_path,out_dir):
try:
bgr = cv2.imread(input_path)
bgr = cv2.resize(bgr, (480, 480))
i420 = cv2.cvtColor(bgr, cv2.COLOR_BGR2YUV_I420)
height = bgr.shape[0]
width = bgr.shape[1]
u = i420[height: height + height // 4, :]
u = u.reshape((1, height // 4 * width))
v = i420[height + height // 4: height + height // 2, :]
v = v.reshape((1, height // 4 * width))
uv = np.zeros((1, height // 4 * width * 2))
uv[:, 0::2] = v
uv[:, 1::2] = u
uv = uv.reshape((height // 2, width))
nv21 = np.zeros((height + height // 2, width))
nv21[0:height, :] = i420[0:height, :]
nv21[height::, :] = uv
#output_name = input_path.rsplit('.', 1)[0] + ".yuv"
output_name = out_dir +input_path.split("/")[-1].rsplit('.', 1)[0] + ".yuv"
nv21.astype("int8").tofile(output_name)
except Exception as except_err:
print(except_err)
return 1
else:
return 0
2.C++版本
cv::Mat image = cv::imread("test.png");
int image_h = image.rows;
int image_w = image.cols;
int image_c = image.channels();
cv::imshow("image", image);
//cv::waitKey();
// 转换到I420
cv::Mat I420; // I420格式图像
cv::cvtColor(image, I420, cv::COLOR_BGR2YUV_I420); // 转换I420格式
uint8_t* pI420 = I420.ptr<uint8_t>(); // I420数据指针
int32_t I420_y_s = image_h * image_w; // I420中 Y长度
int I420_uv_h = image_h / 2; // I420中UV高度
int I420_uv_w = image_w / 2; // I420中UV宽度
// 转换到NV12
cv::Mat NV12 = cv::Mat(image_h * 3 / 2, image_w, CV_8UC1); // NV12格式图像
uint8_t* pNV12 = NV12.ptr<uint8_t>(); // NV12数据指针
memcpy(pNV12, pI420, I420_y_s); // 拷贝I420中的Y数据到NV12中
uint8_t* pI420_U = pI420 + I420_y_s; // 移动I420中U分量指针到U数据头部
uint8_t* pI420_V = pI420_U + I420_uv_h * I420_uv_w; // 移动I420中V分量指针到V数据头部
pNV12 = pNV12 + I420_y_s; // 移动NV12指针到U数据头部
for (int i = 0; i < I420_uv_h * I420_uv_w; i++)
{
// 遍历I420中UV分量数据,复制到NV12中
// 把I420中U数据复制到NV12中U数据对应位置
*pNV12 = *pI420_U;
pNV12++;
pI420_U++;
// 把I420中V数据复制到NV12中V数据对应位置
*pNV12 = *pI420_V;
pNV12++;
pI420_V++;
}
// 保存转换图像
FILE* fp = fopen("ocr_test.yuv", "wb");
int image_len = image_w * image_h * 3 / 2;
fwrite(NV12.ptr<uint8_t>(), image_len, 1, fp);
fclose(fp);
// 读取转换图像
fp = fopen("ocr_test.yuv", "rb");
unsigned char* image_buf = new unsigned char[image_len];
fread(image_buf, image_len, 1, fp);
fclose(fp);
// 显示转换图像
cv::Mat image2 = cv::Mat(image_h * 3 / 2, image_w, CV_8UC1, image_buf);
cv::cvtColor(image2, image2, cv::COLOR_YUV2BGR_NV12);
cv::imshow("image2", image2);
cv::waitKey();
return 0;