设置nv12的矩形边框
来源:互联网 发布:诲女知之乎 读法 编辑:程序博客网 时间:2024/06/04 19:16
NV12
一个6*4的nv12格式的图片的三个分量YUV的内存形式:
虽然nv12的像素大小是width*height,但是必须为nv12图片分配width*height*3/2的内存空间,因为Y分量所占的内存为width*height,而U,V分量各占width*height/4,见上图即一目了然。
nv12分量YUV分量内存操作:可以用双重for循环遍历nv12各个分量的内存分布,从而实现给nv12图片赋予不同的颜色。
由内存YUV分量内存分布图可以知道:
0 ~ width*height 为Y分量存储的内存范围。
width*height ~ width*height*3/2 为UV交叉存储的内存范围。
操作Y分量:buf[j * width + k]
操作U分量 : buf[j / 2 * width + k - k % 2 + width * height]
操作V分量 : buf[j / 2 * width + k - k % 2 + width * height + 1]
在nv12格式的图片上画一个锁定某个目标的矩形方框图
#include <stdio.h>#include <stdlib.h>int nv12_border(char *pic, int pic_w, int pic_h, int rect_x, int rect_y, int rect_w, int rect_h, int R, int G, int B);int main(){ /* Set up the nv12's pixel size */ const int pic_w = 1920; const int pic_h = 1080; /* Set up test data's path and output data's path */ char *inputPathname = "/home/flypei/work/nv12-marked-rect/data/videotestsrc_1920x1080.nv12"; char *outputPathname = "./outputFile.nv12"; FILE *fin = fopen(inputPathname , "rb+"); FILE *fout = fopen(outputPathname, "wb+"); /* Allocate memory for nv12 */ unsigned char *buf = (unsigned char *)malloc(pic_w * pic_h * 3 / 2); /* Read file data to buffer */ fread(buf, 1, pic_w * pic_h * 3 / 2, fin); /* Draw rectangle border to nv12 */ nv12_border(buf, pic_w, pic_h, 500, 500, 300, 400, 0, 0, 255); /* Write data of buf to fout */ fwrite(buf, 1, pic_w * pic_h * 3 / 2, fout); /* Free the allocation memory */ free(buf); /* Close the file */ fclose(fin); fclose(fout); return 0;}int nv12_border(char *pic, int pic_w, int pic_h, int rect_x, int rect_y, int rect_w, int rect_h, int R, int G, int B){ /* Set up the rectangle border size */ const int border = 5; /* RGB convert YUV */ int Y, U, V; Y = 0.299 * R + 0.587 * G + 0.114 * B; U = -0.1687 * R + 0.3313 * G + 0.5 * B + 128; V = 0.5 * R - 0.4187 * G - 0.0813 * B + 128; /* Locking the scope of rectangle border range */ int j, k; for(j = rect_y; j < rect_y + rect_h; j++){ for(k = rect_x; k < rect_x + rect_w; k++){ if (k < (rect_x + border) || k > (rect_x + rect_w - border) ||\ j < (rect_y + border) || j > (rect_y + rect_h - border)){ /* Components of YUV's storage address index */ int y_index = j * pic_w + k; int u_index = (y_index / 2 - pic_w / 2 * ((j + 1) / 2)) * 2 + pic_w * pic_h; int v_index = u_index + 1; /* set up YUV's conponents value of rectangle border */ pic[y_index] = Y ; pic[u_index] = U ; pic[v_index] = V ; } } } return 0;}
原nv12图片(用yuvplayer查看):
加上方框的nv12图片(用yuvplayer查看):
demo优化版
#include <stdio.h>#include <stdlib.h>#define uchar unsigned chartypedef struct rectangle{ int x; int y; int w; int h; uchar thin; uchar YUV[3];}RECT;void RgbToYuv(uchar RGB[], uchar YUV[]);void FindAxis(RECT rect[], int n, int rect_all_axis[]);void DrawWidthLine(uchar* pic, int pic_w, int pic_h, RECT rect[], int n, int axis[]);void DrawHeightLine(uchar* pic, int pic_w, int pic_h, RECT rect[], int n, int axis[]);void DrawPoint(uchar* pic, int pic_w, int pic_h, int point_axis[], int count, uchar YUV[]);void NV12MarkRect(uchar* pic, int pic_w, int pic_h, RECT rect[], int n, int point_axis[], int count);int main(){ /*****************************************************/ /**** ****/ /**** Configure Parameter ****/ /**** ****/ /*****************************************************/ /* Config the nv12's pixel size */ const int pict_w = 1920; const int pict_h = 1080; int picSize = pict_w * pict_h * 1.5; /* Allocate memory for nv12 */ uchar* picBuf = (unsigned char *)malloc(picSize); /* RGB convert to YUV */ uchar RGBblue[3] = {255, 0, 0}; uchar YUVblue[3]; RgbToYuv(RGBblue, YUVblue); /* Config rectangle's quanlity and parameter */ int n = 2; uchar t = 1; RECT Rect[] = { { .x = 0, .y = 0, .w = 96, .h = 96, .thin = t, .YUV[0] = YUVblue[0], .YUV[1] = YUVblue[1], .YUV[2] = YUVblue[2] }, { .x = 144, .y = 144, .w = 128, .h = 128, .thin = t, .YUV[0] = YUVblue[0], .YUV[1] = YUVblue[1], .YUV[2] = YUVblue[2] } }; /* Config point axis's count and draw the point at NV12 */ int c = 30; int point[] = { 12,233, 132,15, 142,22, 312,34, 112,45, 212,58, 127,62, 132,72, 212,84, 129,91, 112,66, 187,38, 155,13, 145,56, 134,23, 165,56, 176,67, 189,87, 174,52, 121,99, 212,66, 287,38, 255,13, 245,56, 234,23, 265,56, 276,67, 289,87, 274,52, 221,99 }; /* Config input and output path */ char input[255] = "videotestsrc_1920x1080.nv12"; char output[255] = "outputFile.nv12"; /******************************************************/ FILE *fin = fopen(input, "rb"); FILE *fout = fopen(output, "wb+"); /* Read file data to buffer */ fread(picBuf, 1, picSize, fin); /* Draw rectangle and point to nv12 */ NV12MarkRect(picBuf, pict_w, pict_h, Rect, n, point, c); /* Write data of buf to fout */ fwrite(picBuf, 1, picSize, fout); /* Free the allocation memory */ free(picBuf); /* Close the file */ fclose(fin); fclose(fout); return 0;}void RgbToYuv(uchar RGB[3], uchar YUV[3]){ /* RGB convert YUV */ YUV[0] = 0.299 * RGB[0] + 0.587 * RGB[1] + 0.114 * RGB[2]; YUV[1] = -0.1687 * RGB[0] + 0.3313 * RGB[1] + 0.5 * RGB[2] + 128; YUV[2] = 0.5 * RGB[0] - 0.4187 * RGB[1] - 0.0813 * RGB[2] + 128;}void FindAxis(RECT rect[], int n, int axis[]){ axis[0] = axis[2] = axis[4] = rect[n].x; axis[6] = rect[n].x + rect[n].w - rect[n].thin; axis[1] = rect[n].y; axis[3] = rect[n].y + rect[n].h - rect[n].thin; axis[5] = axis[7] = rect[n].y + rect[n].thin;}void DrawWidthLine(uchar* pic, int pic_w, int pic_h, RECT rect[], int n, int axis[]){ int i, j, k; int y_index, u_index, v_index; for (i = 0; i < 4; i += 2){ for (j = axis[i+1]+rect[n].thin-1; j >= axis[i+1]; j--){ for (k = axis[i]+rect[n].w-1; k >= axis[i]; k--){ y_index = j * pic_w + k; u_index = ((j >> 1) + pic_h) * pic_w + k - (k & 1); //u_index = (((y_index >> 1) - (pic_w >> 1) * ((j + 1) >> 1)) << 1) + pic_w * pic_h; v_index = u_index + 1; pic[y_index] = rect[n].YUV[0]; pic[u_index] = rect[n].YUV[1]; pic[v_index] = rect[n].YUV[2]; } } }}void DrawHeightLine(uchar* pic, int pic_w, int pic_h, RECT rect[], int n, int axis[]){ int i, j, k; int y_index, u_index, v_index; for (i = 4; i < 8; i += 2){ for (k = axis[i]+rect[n].thin-1; k >= axis[i]; k--){ for (j = axis[i+1]+rect[n].h-(2*rect[n].thin)-1; j >= axis[i+1]; j--){ y_index = j * pic_w + k; u_index = ((j >> 1) + pic_h) * pic_w + k - (k & 1); //u_index = (((y_index >> 1) - (pic_w >> 1) * ((j + 1) >> 1)) << 1) + pic_w * pic_h; v_index = u_index + 1; pic[y_index] = rect[n].YUV[0]; pic[u_index] = rect[n].YUV[1]; pic[v_index] = rect[n].YUV[2]; } } }}void DrawPoint(uchar* pic, int pic_w, int pic_h, int point_axis[], int count, uchar YUV[]){ /* Draw points at NV12 */ int a, y_point, u_point, v_point; for (a = (count-1)*2; a >= 0; a -= 2){ y_point = point_axis[a+1] * pic_w + point_axis[a]; u_point = ((point_axis[a+1] >> 1) + pic_h) * pic_w + point_axis[a] - (point_axis[a] & 1); //u_point = (((y_point >> 1) - (pic_w >> 1) * ((point_axis[a+1] + 1) >> 1)) << 1) + pic_w * pic_h; v_point = u_point + 1; pic[y_point] = YUV[0]; pic[u_point] = YUV[1]; pic[v_point] = YUV[2]; }}void NV12MarkRect(uchar* pic, int pic_w, int pic_h, RECT rect[], int num, int point_axis[], int count){ int i; int axis[8]; for (i = num-1; i >= 0; i--){ FindAxis(rect, i, axis); DrawWidthLine(pic, pic_w, pic_h, rect, i, axis); DrawHeightLine(pic, pic_w, pic_h, rect, i, axis); } DrawPoint(pic, pic_w, pic_h, point_axis, count, rect[0].YUV);}
阅读全文
0 0
- 设置nv12的矩形边框
- android shape设置矩形边框圆角大于某个值无效的解决办法
- 绘制一个蓝色边框的矩形.doc
- 实现圆角矩形边框的方法
- 定制圆角带背景色的矩形边框
- Android 带边框的圆角矩形
- NV12 图像的线性插值
- nv12 图像的旋转
- UITextView 边框的设置
- UITextView 边框的设置
- 设置tr的边框
- android的边框设置
- 控件的边框设置
- Android shape 矩形边框
- 圆角矩形 边框
- NV12 图像数据的旋转
- NV12 数据的抠图
- NV12 和 NV21的区别
- Python数据处理 numpy.median
- [LOJ#2290][THUWC 2017][概率][状压][DP][陈老师神题]随机二分图
- osg::NotifyHandler
- CSS三大特性继承性,层叠性,优先级
- java种前后台线程和进程的关系
- 设置nv12的矩形边框
- 扫描软Agisoft.PhotoScan.Professional.v1.3.2.4164 x64
- 「LibreOJ β Round #2」DP 一般看规律
- 2017上海市高校程序设计邀请赛_L
- MediaPlayer
- 2017.7.4
- java代理
- Java模板方法模式
- nginx启动错误