GTK渲染摄像头图像数据

GTK渲染摄像头图像数据

1.GDK简介

  绘图工具集(GDK,Graphics Drawing Kit)是在GTK+ 和特定操作系统的应用编程接口(API,Application Program Interface)之间的低级绘图制层—— Linux的API是Xlib。由于GTK和机器的API之间没有直接接口,移植GTK+就成为移植GLIB和GDK的问题。GDK提供像元的绘制能力以及低层的窗口建立和处理能力。对许多应用来说,使用构件时最方便的,但是,如果你想用GTK+编写模拟时钟的应用程序,由于它没有绘制时钟表面的能力,实现这样的任务就有困难了。使用带GDK的绘图区(drawing area)构件代替封装(canned)的构件,即可绘制出任何你需要绘制的内容。

2.绘图子程序

  使用GDK子程序编写应用程序并不比直接使用Xlib好多少。幸运的是,GTK+提供一种构件,即绘图区(drawing area)构件。你可以用它来建立需要的手工绘图的应用。可以像使用其它GTK+构件一样使用绘图区构件。而且,使用该构件建立依赖图形的应用也足够灵活,这种方法的优点是可以在同一应用中使用GTK+和GDK。GTK+提供菜单、工具条和其它构件,支持在绘图区构件内进行绘图,而GDK则提供用于绘制线、框、像元、圆和其它图形的API。
  每个GDK子程序至少取两个参数:可绘制区(GdkDrawable)和GDKGC。GdkDrawable表示可以在他上面进行绘图的区域,GDKGC包函数颜色和字体信息以及其它绘图信息。

3.Linux下摄像头编程

  V4L2是Video for linux2的简称,为linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video*下,如果只有一个视频设备,通常为/dev/video0。
  v4L2是针对uvc免驱usb设备的编程框架 ,主要用于采集usb摄像头等。

  • 摄像头框架编程步骤

  (1)打开摄像头设备(/dev/video0 、/dev/video1 )。
  (2)设置图像格式:VIDIOC_S_FMT(视频捕获格式、图像颜色数据格式、图像宽和高)。
  (3)申请缓冲区:VIDIOC_REQBUFS(缓冲区数量、缓冲映射方式、视频捕获格式)。
  (4)将缓冲区映射到进程空间:VIDIOC_QUERYBUF(要映射的缓冲区下标、缓冲映射方式、视频捕获格式)。
  (5)将缓冲区添加到队列中:VIDIOC_QBUF(映射的缓冲区下标、缓冲映射方式、视频捕获格式)。
  (6)开启摄像头采集:VIDIOC_STREAMON (视频捕获格式)。
  (7)从采集队列中取出图像数据VIDIOC_DQBUF,进行图像渲染。

摄像头编程示例参考: https://blog.csdn.net/weixin_44453694/article/details/126488841

  • 摄像头采集示例
#include <stdio.h>
#include <linux/videodev2.h> //摄像头头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>
#include "camera.h"
/*摄像头初始化*/
int Camera_Init(struct _CAMERA *video_info)
{int i=0;/*1.打开摄像头设备*/int fd=open(VIDEO_DEV,2);if(fd<0)return -1;//摄像头打开失败/*2.设置摄像头捕获格式*/struct v4l2_format v4l2fmt;memset(&v4l2fmt,0,sizeof(v4l2fmt));//初始化结构体v4l2fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式v4l2fmt.fmt.pix.width=640;//图像宽度v4l2fmt.fmt.pix.height=480;//图像高度v4l2fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;//YUYV颜色编码格式if(ioctl(fd,VIDIOC_S_FMT,&v4l2fmt))return -2;//设置格式失败printf("采集图像大小:%d*%d\n",v4l2fmt.fmt.pix.width,v4l2fmt.fmt.pix.height);video_info->image_w=v4l2fmt.fmt.pix.width;video_info->image_h=v4l2fmt.fmt.pix.height;/*3.申请缓冲区*/struct v4l2_requestbuffers v4l2reqbuf;memset(&v4l2reqbuf,0,sizeof(v4l2reqbuf));//初始化结构体v4l2reqbuf.count=4;//申请的缓冲区个数v4l2reqbuf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式v4l2reqbuf.memory=V4L2_MEMORY_MMAP;//内存映射if(ioctl(fd,VIDIOC_REQBUFS,&v4l2reqbuf))return -3;//申请缓冲区失败printf("申请的缓冲区个数:%d\n",v4l2reqbuf.count);/*4.将缓冲区映射到进程空间*/struct v4l2_buffer v4l2buf;memset(&v4l2buf,0,sizeof(v4l2buf));//初始化结构体v4l2buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式v4l2buf.memory=V4L2_MEMORY_MMAP;//内存映射for(i=0;i<v4l2reqbuf.count;i++){v4l2buf.index=i;/*缓冲区下标*/if(ioctl(fd,VIDIOC_QUERYBUF,&v4l2buf))return -4;//申请缓冲区失败video_info->video_buff[i]=mmap(NULL,v4l2buf.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,v4l2buf.m.offset);printf("video_buff[%d]=%p\n",i,video_info->video_buff[i]);}video_info->video_len=v4l2buf.length;//yuv图像数据字节数printf("yuv_size=%d\n",video_info->video_len);/*5.将映射的空间添加到采集队列*/memset(&v4l2buf,0,sizeof(v4l2buf));//初始化结构体v4l2buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式v4l2buf.memory=V4L2_MEMORY_MMAP;//内存映射for(i=0;i<v4l2reqbuf.count;i++){v4l2buf.index=i;/*缓冲区下标*/if(ioctl(fd,VIDIOC_QBUF,&v4l2buf))return -5;//添加到采集队列失败}/*6.开启摄像头*/int type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式if(ioctl(fd,VIDIOC_STREAMON,&type))return -6;//启动摄像头失败video_info->video_fd=fd;//摄像头描述符return 0;//初始化成功返回0
}

4.GDK渲染

#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/videodev2.h>
#include <sys/mman.h>
#include <gtk/gtk.h>#include <time.h>
#include "camera.h"
struct _CAMERA video_info;/*设备结构体信息*/
int width,height;//图像宽高
guchar *rgbbuf=NULL;//保存rgb颜色数据
GtkWidget *drawarea;int on_delete_event(GtkWidget *widget,GdkEvent *event,gpointer data)
{  /*释放资源*/g_print("释放资源\n");for(int i=0;i<4;i++){munmap(video_info.video_buff[i],video_info.video_len);}free(rgbbuf);close(video_info.video_fd); gtk_main_quit();return FALSE;
}int draw_image(GtkWidget *widget,GdkEvent *event,gpointer data)
{ gdk_draw_rgb_image(widget->window,widget->style->fg_gc[GTK_STATE_NORMAL],0,0,width,height,GDK_RGB_DITHER_NONE,rgbbuf,width*3);return FALSE;
}
/*YUYV转RGB888*/
void yuv_to_rgb(unsigned char *yuv_buffer,unsigned char *rgb_buffer,int iWidth,int iHeight)
{int x;int z=0;unsigned char *ptr = rgb_buffer;unsigned char *yuyv= yuv_buffer;for (x = 0; x < iWidth*iHeight; x++){int r, g, b;int y, u, v;if (!z)y = yuyv[0] << 8;elsey = yuyv[2] << 8;u = yuyv[1] - 128;v = yuyv[3] - 128;b = (y + (359 * v)) >> 8;g = (y - (88 * u) - (183 * v)) >> 8;r = (y + (454 * u)) >> 8;*(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);*(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);*(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);if(z++){z = 0;yuyv += 4;}}
}int read_data(GtkWidget * widget,GdkEvent * event,gpointer data)
{    /*读取摄像头图像数据*/struct v4l2_buffer v4l2buf;memset(&v4l2buf,0,sizeof(v4l2buf));//初始化结构体v4l2buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式v4l2buf.memory=V4L2_MEMORY_MMAP;//内存映射if(ioctl(video_info.video_fd,VIDIOC_DQBUF,&v4l2buf)==-1){printf("Dqbuf failed\n");return FALSE;}//将yuyv转换为rgb24yuv_to_rgb(video_info.video_buff[v4l2buf.index],rgbbuf,width,height);/*保证线程安全,上锁*/gdk_threads_enter();gdk_draw_rgb_image(drawarea->window,drawarea->style->fg_gc[GTK_STATE_NORMAL],0,0,width,height,GDK_RGB_DITHER_NONE,rgbbuf,width*3);/*保证线程安全,释放*/gdk_threads_leave();ioctl(video_info.video_fd,VIDIOC_QBUF,&v4l2buf);//将缓冲区添加回采集队列return TRUE;
}int main (int argc,char *argv[])
{/*摄像头初始化*/int ret=Camera_Init(&video_info);if(ret){printf("摄像头打开失败ret=%d\n",ret);return 0;}/*图像宽高*/width=video_info.image_w;height=video_info.image_h;rgbbuf=malloc(width*height*3);/* init Gtk */GtkWidget *window;/*gtk初始化*/gtk_init(&argc,&argv);/*创建窗口*/window=gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_window_set_title(GTK_WINDOW(window),"摄像头采集");/*固定窗口大小*/gtk_window_set_resizable (GTK_WINDOW(window),FALSE);/*连接信号*/g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(on_delete_event),NULL);/*初始化gdk的rgb*/gdk_rgb_init();gtk_widget_push_visual(gdk_rgb_get_visual());gtk_widget_push_colormap(gdk_rgb_get_cmap());/*创建绘图区域*/drawarea=gtk_drawing_area_new();gtk_widget_pop_visual();gtk_widget_pop_colormap();gtk_container_add(GTK_CONTAINER(window),drawarea);g_signal_connect(G_OBJECT(drawarea),"expose_event",G_CALLBACK(draw_image),NULL);guint id=gtk_idle_add((GtkFunction)read_data,NULL);/*设置窗口大小*/gtk_widget_set_size_request(GTK_WIDGET(drawarea),width,height);gtk_widget_show_all(window);gtk_main();gdk_threads_leave();return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/22290.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pheatmap热图的绘制及如何调整图片

Pheatmap热图的绘制及如何调整图片 Pheatmap包是R语言绘制热图比较强大的软件包&#xff0c;当然现在也有很多资料介绍这个包的使用&#xff0c;但是今天我写的重点不是如何使用这个包绘制热图&#xff0c;而是如何绘制出更好看的热图。&#xff08;我使用的矩阵是1663x594&am…

unity可视化图表插件XCharts绘制折线图、饼图、柱状图

一、简介 一款基于UGUI的功能强大、易用、参数可配置的数据可视化图表插件。支持折线图、柱状图、饼图、雷达图、散点图、热力图等常见图表。 特性&#xff1a; 内置丰富示例和模板&#xff0c;参数可视化配置&#xff0c;效果实时预览&#xff0c;纯代码绘制。 支持折线图、柱…

日语学习软件推荐——五十音图APP:AI纠正你的日语发音

每个自学日语的人&#xff0c;想必都经历过“哑巴日语”的苦恼。收集了很多学习资料&#xff0c;努力积累词汇量&#xff0c;一开口却暴露了“散装口语”的短板。 但是现在就不怕这个问题啦&#xff0c;五十音图APP可以让你从入门开始&#xff0c;练就一口流利的地道日语&…

白痴学日语系列之初识日语(二)

每日记单词 間[あいだ]0 a i da 间&#xff0c;间隔 【记】あい&#xff08;合い→互相之间&#xff09;だ&#xff08;是&#xff09;→间隔 青[あお]1 a o 蓝色&#xff1b;青色&#xff1b;绿色&#xff1b;不成熟 【记】あ&#xff08;上&#xff09;お&#xff08;う→…

新标日语学习笔记

文章目录 新标日语学习笔记第一章 日语入门1.1 五十音1.2 日语声调1.2.1 声调理解1.2.2 高低音发音1.2.3 简单的高低音发音练习 1.3 浊音和长音1.3.1 浊音1.3.2 长音 1.4 促音和拗音 第二章 课文与笔记2.1 小李是中国人2.1.1 单词2.1.2 语法 新标日语学习笔记 第一章 日语入门…

日语语音识别_日语语音识别软件_日语语音识别在线 - 云+社区 - 腾讯云

广告关闭 腾讯云双11爆品提前享&#xff0c;精选热门产品助力上云&#xff0c;云服务器首年88元起&#xff0c;买的越多返的越多&#xff0c;最高满返5000元&#xff01; 语气词过滤和句末标点过滤用户自主选择功能 新功能发布录音文件识别产品上线音视频领域模型 新功能发布…

C++制作一款小黑子键盘提示音程序

不好意思我漏出鸡脚了。 首先讲一下思路&#xff0c;这次制作的小黑子相当于键盘提示音&#xff0c;输入J,N,T,M&#xff0c;会发出“鸡你太美”的声音&#xff0c;连续按下JNTM则会发出“你干嘛啊&#xff0c;哎呦”的声音。 完整的工程和代码以及成品已经上传至百度网盘&…

只因小黑子:css动画复习

小黑子的css动画复习 css动画1. transiton 动画过渡1.1 transiton: 某属性1.2 transiton: all2. 动画过渡类型3. 动画过渡单一属性4. transform 2d属性4.1 translate 平移一、translateX(参数) 水平平移二、translateY(参数) 上下平移三、translate(a,b) 水平&#xff0c;上下平…

小黑子的HTML入土过程

小黑子的HTML入土过程 1. HTMLCSS系列教程第一章1.1 了解什么是HTML和CSS1.2 编译器VS Code1.2.1 下载方式和设置1.2.2 VS Code的快捷键基础用法 1.3 了解网页开发1.4 Web前端的三大核心技术1.5 HTML的基本结构和属性1.6 HTML的初始代码1.7 HTML的注释1.8 HTML的语义化1.9 标题…

Python画图之小黑子头像

效果演示 &#x1f438;真爱粉必备知识 倍速*2.0 实现步骤 设置窗口大小和绘画速度。用 penup() 和 goto() 来定位&#xff0c;画出领子和衣服&#xff0c;使用 fillcolor() 和 begin_fill() 开始填充颜色。用 pensize() 和 pencolor() 来调整线条的大小和颜色&#xff0c;画…

用 ChatGPT 秒建大模型,OpenAI 全新插件杀疯了,接入代码解释器一键 get

ChatGPT 可以联网后&#xff0c;OpenAI 还火速介绍了一款代码生成器&#xff0c;在这个插件的加持下&#xff0c;ChatGPT 甚至可以自己生成机器学习模型了。 上周五&#xff0c;OpenAI 刚刚宣布了惊爆的消息&#xff0c;ChatGPT 可以联网&#xff0c;接入第三方插件了&#xf…

什么是元宇宙,什么是AI,什么是chatgpt?什么是星云虚境?

随着现代科技的发展&#xff0c;元宇宙已经不再是科幻电影中的概念&#xff0c;而是逐渐变得真实起来。元宇宙是极为先进的数字世界&#xff0c;它需要人工智能、虚拟现实、区块链、云计算等多种技术的支持。在这个数字空间中&#xff0c;人们可以体验到比现实生活更丰富、更多…

元宇宙大爆炸:开发元宇宙是互联网的接替者?

美国游戏引擎公司Epic Games的创始人CEO蒂姆斯威尼&#xff08;Tim Sweeney&#xff09;宣称&#xff0c;玩家已经可以通过风靡的《堡垒之夜》聚集“元宇宙”的虚拟世界中。近期&#xff0c;美国超人气歌手Ariana Grande在全球不同地区&#xff0c;连续举办了5场演唱会&#xf…

“抢滩”元宇宙:不只Facebook和腾讯

来源 | 01区块链 责编 | Carol Facebook创始人兼首席执行官马克扎克伯格在2021年6月底表示&#xff0c;该公司的未来规划远不止是社交媒体&#xff0c;而是筑造一个元宇宙。扎克伯克宣称&#xff0c;希望在未来用5年左右的时间&#xff0c;将Facebook打造为一家元宇宙公司。 20…

元宇宙GOD新纪元打通元宇宙

J,F,4.5.9.9.9 区块链技术诞生至今已经有十余年了。在国内外不同团队的大力推动下&#xff0c;区块链项目层出不穷&#xff0c;但是对于生活的赋能作用并没有很好地体现出来。区块链技术是一项伟大的革命&#xff0c;但是一项技术如果不能投入实用&#xff0c;和各领域的应用结…

科技新浪推前浪 ChatGPT将元宇宙“拍在沙滩上”?

近期ChatGPT的热度显然已经盖过了元宇宙&#xff0c;回想去年元宇宙大热之际&#xff0c;很多企业纷纷跟进&#xff0c;甚至还有不少公司选择更名以表达All In元宇宙的决心。而如今ChatGPT抢占风头&#xff0c;成为新宠&#xff0c;元宇宙似乎被“抛弃”了&#xff0c;难道元宇…

巴比特 | 元宇宙每日必读:ChatGPT的火热与当年元宇宙的爆火故事如出一辙,科技巨头为何总是喜新厌旧?...

摘要&#xff1a;几乎所有公司都在想方设法与ChatGPT攀上关系&#xff0c;几乎人人都在关注、讨论、试用ChatGPT时&#xff0c;谁还记得Roblox、Clubhouse&#xff1f;Roblox是ChatGPT之前的全球顶流&#xff0c;带火了元宇宙&#xff1b;Clubhouse在Roblox之前也曾短暂红遍全球…

ChatGPT提示词工程(三):Summarizing概括总结

目录 一、说明二、安装环境三、概括总结&#xff08;Summarizing&#xff09;1. 简单地概括总结&#xff0c;只有字数限制2. 概括总结需要关注的某些点 四、用“提取”代替“总结”&#xff08;Try "extract" instead of "summarize"&#xff09;五、概括总…

微信小程序自定义tabbar,custom-tab-bar

背景&#xff1a; 由于需要按权限配置底部tabbar&#xff0c;所以需要用到自定义&#xff0c;微信官方文档自定义 tabBar 1. 配置信息 在 app.json 中的 tabBar 项指定 custom 字段&#xff0c;同时其余 tabBar 相关配置也补充完整 {"tabBar": {"custom": …