📄 main2.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <termios.h>
#inclide <iostream>
#include "fb.h"
#include "videodev.h"
#include "bmp.h"
#include "grab-ng.h"
#define _GNU_SOURCE
#include <getopt.h>
struct capture_info{
int width, height;
char device[256];
};
struct fb_dev
{
//for frame buffer
int fb;
void *fb_mem; //frame buffer mmap
int fb_width, fb_height, fb_line_len, fb_size;
int fb_bpp;
//src must be RGB24 format
void (*fb_draw)(struct fb_dev *fbdev, void* src, int x, int y, int width, int height);
};
static char *default_framebuffer="/dev/fb0";
static struct capture_info capinfo={320, 240, "/dev/v4l/video0"};
static struct fb_dev fbdev;
static char* fb_dev_name=NULL;
struct ng_video_buf* pvideo_buf;
char *bmpName="/root/Documents/ndt.bmp";
double x=0,y=0;
#define NUM_CAPBUFFER 32
void fb_draw16bpp(struct fb_dev *fbdev, void* src, int x, int y, int width, int height)
{
int i, j;
int fb_line_len = fbdev->fb_line_len;
__u8 *psrc= (__u8*)src;
__u16* pdsc = (__u16*)fbdev->fb_mem;
__u16 tmp, tmp1;
pdsc+=y*fb_line_len/2 + x;
for(i=0; i<height; i++){
for(j=0; j<width; j++){
/*
tmp = (*psrc)>>3; tmp<<=11; *psrc++; //this is for GIGEND----PC
tmp1 = (*psrc)>>2; tmp|=(tmp1<<5); *psrc++;
tmp |= (*psrc)>>3; *psrc++;
pdsc[j] = tmp;
*/
//this is for little end ----ARM
tmp = (*psrc)>>3; tmp<<=0; *psrc++; //BLUE
tmp1 = (*psrc)>>2; tmp|=(tmp1<<5); *psrc++; //GREEN
tmp |=(((*psrc)>>3) << 11); *psrc++; //RED
pdsc[j] = tmp;
}
pdsc+=fb_line_len/2;
}
}
void fb_draw12bpp(struct fb_dev *fbdev, void* src, int x, int y, int width, int height)
{
int i, j;
int fb_line_len = fbdev->fb_line_len;
__u8 *psrc= (__u8*)src;
__u8* pdsc = (__u8*)fbdev->fb_mem;
__u8 tmp;
//fixed me! x must be even
pdsc+=y*fb_line_len + x*3/2;
for(i=0; i<height; i++){
for(j=0; j<width*3/2;){
tmp = psrc[2]&0xf0;
tmp |=(psrc[1]>>4);
pdsc[j++] = tmp;
tmp = psrc[0]&0xf0;
tmp |=(psrc[5]>>4);
pdsc[j++] = tmp;
tmp = psrc[4]&0xf0;
tmp |=(psrc[3]>>4);
pdsc[j++] = tmp;
psrc+=6;
}
pdsc+=fb_line_len;
}
}
int framebuffer_open(void)
{
int fb;
struct fb_var_screeninfo fb_vinfo;
struct fb_fix_screeninfo fb_finfo;
if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER")))
fb_dev_name=default_framebuffer;
fb = open (fb_dev_name, O_RDWR);
if(fb<0){
printf("device %s open failed\n", fb_dev_name);
return -1;
}
if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_vinfo)) {
printf("Can't get VSCREENINFO: %s\n", strerror(errno));
close(fb);
return -1;
}
if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_finfo)) {
printf("Can't get FSCREENINFO: %s\n", strerror(errno));
return 1;
}
fbdev.fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
fb_vinfo.blue.length + fb_vinfo.transp.length;
fbdev.fb_width = fb_vinfo.xres;
fbdev.fb_height = fb_vinfo.yres;
fbdev.fb_line_len = fb_finfo.line_length;
fbdev.fb_size = fb_finfo.smem_len;
printf("frame buffer: %dx%d, %dbpp, 0x%xbyte\n",
fbdev.fb_width, fbdev.fb_height, fbdev.fb_bpp, fbdev.fb_size);
switch(fbdev.fb_bpp){
case 16:
fbdev.fb_draw = fb_draw16bpp;
break;
case 12:
fbdev.fb_draw = fb_draw12bpp;
break;
default:
printf("Can't support %d bpp draw\n", fbdev.fb_bpp);
return -1;
}
fbdev.fb_mem = mmap (NULL, fbdev.fb_size, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
if(fbdev.fb_mem==NULL || (int)fbdev.fb_mem==-1){
fbdev.fb_mem=NULL;
printf("mmap failed\n");
close(fb);
return -1;
}
fbdev.fb=fb;
memset (fbdev.fb_mem, 0x0, fbdev.fb_size);
return 0;
}
void framebuffer_close()
{
if(fbdev.fb_mem){
munmap(fbdev.fb_mem, fbdev.fb_size);
fbdev.fb_mem=NULL;
}
if(fbdev.fb){
close(fbdev.fb);
fbdev.fb=0;
}
}
int capture()
{
void* caphandle;
struct ng_vid_driver *cap_driver = &v4l_driver;
struct ng_video_fmt fmt;
fmt.fmtid = VIDEO_BGR24;
fmt.width = capinfo.width;
fmt.height = capinfo.height;
if(framebuffer_open()<0){
return -1;
}
caphandle=cap_driver->open(capinfo.device);
if(!caphandle){
printf("failed to open video for linux interface!\n");
return -1;
}
if(cap_driver->setformat(caphandle, &fmt)){
printf("failed to set video format!\n");
return -1;
}
cap_driver->startvideo(caphandle, 25, NUM_CAPBUFFER);
{
int x, y, width, height;
int diff_width, diff_height;
diff_width = fbdev.fb_width - fmt.width;
diff_height = fbdev.fb_height - fmt.height;
if(diff_width>0){
x = diff_width/2;
width = fmt.width;
}
else{
x = 0;
width = fbdev.fb_width;
}
if(diff_height>0){
y = diff_height/2;
height = fmt.height;
}
else{
y = 0;
height = fbdev.fb_height;
}
//begin capture
while(1){
pvideo_buf=cap_driver->nextframe(caphandle);
fbdev.fb_draw(&fbdev, pvideo_buf->data, x, y, width, height);
ng_release_video_buf(pvideo_buf);
}
}
framebuffer_close();
cap_driver->stopvideo(caphandle);
cap_driver->close(caphandle);
return 0;
}
const char*program_name;
void print_usage (FILE*stream,int exit_code)
{
fprintf (stream, "Usage:%s options [ inputfile ....]\n",program_name);
fprintf (stream, "-h --help Display this usage information.\n"
"-d --device <video device>.\n "
"-f --framebuffer <frame buffer device>.\n "
"-v --verbose <n>.\n "
"-s --size <320:240>\n");
exit (exit_code);
}
/*采集一副图象,将其写入到bmp文件中,然后读出该bmp图象数据信息,提取数据进行图象识别,计算出图片中
激光光斑的坐标*/
int save_bmp()
{
if(!pvideo_buf->data)
return 0;
int lineByte=(320*24/8+3)/4*4;
FILE *fp=fopen(bmpName,"wb");
if(fp==0)
return 0;
BITMAPFILEHEADER fileHead;
fileHead.bftype = 0x4d42;
fileHead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+lineByte*240;
fileHead.bfReserved1=0;
fileHead.bfReserved2=0;
fileHead.bfoffBits=54;
fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);
BITMAPINFOHEADER head;
head.biBitCount=24;
head.biClrImportant=0;
head.biClrUsed=0;
head.biCompression=0;
head.biHeight=240;
head.biPlanes=1;
head.biSize=40;
head.biSizeImage=lineByte*240;
head.biWidth=320;
head.biPelsPerMeter=0;
head.biYPelsPerMeter=0;
fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);
fwrite(pvideo_buf->data,240*lineByte,1,fp);
fclose(fp);
return 1;
}
int read_bmp()
{
unsigned bmpWidth;
unsigned bmpHeight;
int *pBmpBuf;
FILE *fp=fopen(bmpName,"rb");
if(fp==0)
return 0;
fseek(fp,sizeof(BITMAPFILEHEADER),0);
BITMAPINFOHEADER head;
fread(&head,sizeof(BITMAPINFOHEADER),1,fp);
bmpWidth=head.biWidth;
bmpHeight=head.biHeight;
int lineByte=(bmpWidth*24/8+3)/4*4;
fread(pBmpBuf,1,lineByte*bmpHeight,fp);
fclose(fp);
return 1;
}
//获得图象中心坐标
void get_middle()
{
doublex1=0,y1=0,x2=0;
save_bmp();
//printf("width=%d,height=%d\n",bmpWidth,bmpHeight);
read_bmp();
int i,j,k;
int lineByte=(bmpWidth*24/8+3)/4*4;
for(i=1;i<bmpWidth;i++){
for(j=1;j<bmpHeight;j++){
x1+=(*(pBmpBuf+j*lineByte+i*3+0)*0.11+*(pBmpBuf+j*lineByte+i*3+1)*0.59+*(pBmpBuf+j*lineByte+i*3+2)*0.3)*i
x2+=*(pBmpBuf+i*lineByte+j*3+0)*0.11+*(pBmpBuf+i*lineByte+j*3+1)*0.59+*(pBmpBuf+i*lineByte+j*3+2)*0.3
y1+=(*(pBmpBuf+i*lineByte+j*3+0)*0.11+*(pBmpBuf+i*lineByte+j*3+1)*0.59+*(pBmpBuf+i*lineByte+j*3+2)*0.3)*j
}
}
x=x1/x2;
y=y1/x2;
sleep(10);
}
void send_gprs()
{
int fdcom, i, SendLen;
struct termios termios_cur;
//char RecvBuf[10];
char *p1="AT\r\n";
char *p2="AT+CMGF=1\r\n";
char *p3="AT+CMGS=15123362860\r\n";
p1_length=strlen(p1);
p2_length=strlen(p2);
p3_length=strlen(p3);
fdcom = PortOpen(&portinfo);
if(fdcom<0){
printf("Error: open serial port error.\n");
exit(1);
}
PortSet(fdcom, &portinfo);
SendLen = PortSend(fdcom, p1, p1_length);
if(SendLen>0){
printf("No %d send %d data information.\n", i, SendLen);
}
else{
printf("Error: send failed.\n");
}
SendLen = PortSend(fdcom, p2, p2_length);
if(SendLen>0){
printf("No %d send %d data information.\n", i, SendLen);
}
else{
printf("Error: send failed.\n");
}
SendLen = PortSend(fdcom, p3, p3_length);
if(SendLen>0){
printf("No %d send %d data information.\n", i, SendLen);
}
else{
printf("Error: send failed.\n");
}
char *info_x="11.342",*info_y="6.5643";
//int decpt,sign;
//gcvt(x,5,info_x);
info_x_length=strlen(info_x);
//gcvt(y,5,info_y);
PortSend(fdcom, info_x, info_x_length);
strcat(info_y,"/x1a");
info_y_length=strlen(info_y);
SendLen = PortSend(fdcom, info_y, info_y_length);
if(SendLen>0){
printf("No %d send %d data information.\n", i, SendLen);
}
else{
printf("Error: send failed.\n");
}
sleep(10);
}
static int verbose =0;
int main (int argc,char*argv [])
{
int next_option;
const char*const short_options ="hd:v:f:s:";
const struct option long_options [] ={
{"help",0,NULL,'h' },
{"device",1,NULL,'d' },
{"framebuffer",1,NULL,'f' },
{"verbose",1,NULL,'v' },
{"size",0,NULL,'s' },
{NULL,0,NULL,0 }};
const char*output_filename =NULL;
program_name =argv [0];
do {
next_option =getopt_long (argc,argv,short_options, long_options,NULL);
switch (next_option)
{
case 'h':/*-h or --help */
print_usage (stdout,0);
case 's':/*-s or --size */
//ip =optarg;
sscanf(optarg, "%d:%d", &(capinfo.width), &(capinfo.height));
break;
case 'f':/*-f or --framebuffer */
fb_dev_name = optarg;
break;
case 'd':/*-b or --device */
strcpy(capinfo.device, optarg);
break;
case 'v':/*-v or --verbose */
sscanf(optarg, "%d", &verbose);
ng_debug = verbose;
break;
case '?':/*The user specified an invalid option.*/
print_usage (stderr,1);
case -1:/*Done with options.*/
break;
default:/*Something else:unexpected.*/
print_usage (stderr,1);
}
}while (next_option !=-1);
printf("video %s caputure: %dx%d\n", capinfo.device, capinfo.width, capinfo.height);
pthread_t thread_id1,thread_id2,thread_id3;
pthread_attr_t attr;
struct sched_param param;
pthread_attr_init(&attr);
pthread_attr_getschedparam(&attr,¶m);
pthread_create(&thread_id2,&attr,(void*)&send_gprs,NULL);
pthread_create(&thread_id3,&attr,(void*)&get_nd,NULL);
param.sched_priority++;
pthread_attr_setschedparam(&attr,¶m);
pthread_create(&thread_id1,&attr,(void*)&capture,NULL);
pthread_join(thread_id1,NULL);
pthread_join(thread_id3,NULL);
pthread_join(thread_id2,NULL);
return capture();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -