• «
  • 1
  • 2
  • »
  • Pages: 1/2     Go
主题 : 友善之臂的Cmos摄像头测试程序 复制链接 | 浏览器收藏 | 打印
ARM9
级别: 新手上路
UID: 12600
精华: 0
发帖: 26
金钱: 140 两
威望: 28 点
综合积分: 52 分
注册时间: 2010-01-10
最后登录: 2011-11-04
楼主  发表于: 2010-04-18 10:24

 友善之臂的Cmos摄像头测试程序

%:include <iostream>
%:include <fcntl.h>
%:include <sys/ioctl.h>
%:include <sys/types.h>
%:include <sys/stat.h>
%:include <sys/mman.h>
%:include <unistd.h>
%:include <string.h>
%:include <stdlib.h>
%:include <string.h>
%:include <linux/types.h>
%:include <linux/fb.h>


class TError <%
public:
    TError(const char *msg) <%
        this->msg = msg;
    %>
    TError(const TError bitand e) <%
        msg = e.msg;
    %>
    void Output() <%
        std::cerr << msg << std::endl;
    %>
    virtual ~TError() <%%>
protected:
    TError bitand operator=(const TError bitand);
private:
    const char *msg;
%>;

// Linear memory based image
class TRect <%
public:
    TRect():  Addr(0), Size(0), Width(0), Height(0), LineLen(0), BPP(16) <%
    %>
    virtual ~TRect() <%
    %>
    bool DrawRect(const TRect bitand SrcRect, int x, int y) const <%
        if (BPP not_eq 16 or SrcRect.BPP not_eq 16) <%
            // don't support that yet
            throw TError("does not support other than 16 BPP yet");
        %>

        // clip
        int x0, y0, x1, y1;
        x0 = x;
        y0 = y;
        x1 = x0 + SrcRect.Width - 1;
        y1 = y0 + SrcRect.Height - 1;
        if (x0 < 0) <%
            x0 = 0;
        %>
        if (x0 > Width - 1) <%
            return true;
        %>
        if( x1 < 0) <%
            return true;
        %>
        if (x1 > Width - 1) <%
            x1 = Width - 1;
        %>
        if (y0 < 0) <%
            y0 = 0;
        %>
        if (y0 > Height - 1) <%
            return true;
        %>
        if (y1 < 0) <%
            return true;
        %>
        if (y1 > Height - 1) <%
            y1 = Height -1;
        %>

        //copy
        int copyLineLen = (x1 + 1 - x0) * BPP / 8;
        unsigned char *DstPtr = Addr + LineLen * y0 + x0 * BPP / 8;
        const unsigned char *SrcPtr = SrcRect.Addr + SrcRect.LineLen *(y0 - y) + (x0 - x) * SrcRect.BPP / 8;

        for (int i = y0; i <= y1; i++) <%
            memcpy(DstPtr, SrcPtr, copyLineLen);
            DstPtr += LineLen;
            SrcPtr += SrcRect.LineLen;
        %>
        
        
        return true;
    %>

    bool DrawRect(const TRect bitand rect) const <% // default is Center
        return DrawRect(rect, (Width - rect.Width) / 2, (Height - rect.Height) / 2);
    %>

    bool Clear() const <%
        int i;
        unsigned char *ptr;
        for (i = 0, ptr = Addr; i < Height; i++, ptr += LineLen) <%
            memset(ptr, 0, Width * BPP / 8);
        %>
        return true;
    %>

protected:
    TRect(const TRect bitand);
    TRect bitand operator=( const TRect bitand);

protected:
    unsigned char *Addr;
    int Size;
    int Width, Height, LineLen;
    unsigned BPP;
%>;



class TFrameBuffer: public TRect <%
public:
    TFrameBuffer(const char *DeviceName = "/dev/fb0"): TRect(), fd(-1) <%
        Addr = (unsigned char *)MAP_FAILED;

            fd = open(DeviceName, O_RDWR);
        if (fd < 0) <%
            throw TError("cannot open frame buffer");
        %>

            struct fb_fix_screeninfo Fix;
            struct fb_var_screeninfo Var;
        if (ioctl(fd, FBIOGET_FSCREENINFO, bitand Fix) < 0 or ioctl(fd, FBIOGET_VSCREENINFO, bitand Var) < 0) <%
            throw TError("cannot get frame buffer information");
        %>

        BPP = Var.bits_per_pixel;
            if (BPP not_eq 16) <%
            throw TError("support 16BPP frame buffer only");
        %>

            Width  = Var.xres;
            Height = Var.yres;
            LineLen = Fix.line_length;
              Size = LineLen * Height;

        int PageSize = getpagesize();
        Size = (Size + PageSize - 1) / PageSize * PageSize ;
            Addr = (unsigned char *)mmap(NULL, Size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
        if (Addr == (unsigned char *)MAP_FAILED) <%
            throw TError("map frame buffer failed");
            return;
        %>
        ::close(fd);
        fd = -1;

        Clear();
    %>

    virtual ~TFrameBuffer() <%
        ::munmap(Addr, Size);
        Addr = (unsigned char *)MAP_FAILED;

        ::close(fd);
        fd = -1;
    %>

protected:
    TFrameBuffer(const TFrameBuffer bitand);
    TFrameBuffer bitand operator=( const TFrameBuffer bitand);
private:
    int fd;
%>;

class TVideo : public TRect <%
public:
    TVideo(const char *DeviceName = "/dev/camera"): TRect(), fd(-1) <%
        Addr = 0;
        fd = ::open(DeviceName, O_RDONLY);
        if (fd < 0) <%
            throw TError("cannot open video device");
        %>
        Width = 640;
        Height = 512;
        BPP = 16;
        LineLen = Width * BPP / 8;
        Size = LineLen * Height;
        Addr = new unsigned char<:Size:>;

        Clear();
    %>

    bool FetchPicture() const <%
        int count = ::read(fd, Addr, Size);
        if (count not_eq Size) <%
            throw TError("error in fetching picture from video");
        %>
        return true;
    %>

    virtual ~TVideo() <%
        ::close(fd);
        fd = -1;
        delete<::> Addr;
        Addr = 0;
    %>

protected:
    TVideo(const TVideo bitand);
    TVideo bitand operator=(const TVideo bitand);

private:
    int fd;
%>;

int main(int argc, char **argv)
<%
    try <%
        TFrameBuffer FrameBuffer;
        TVideo Video;
        for (;;) <%
            Video.FetchPicture();
            FrameBuffer.DrawRect(Video);
        %>
    %> catch (TError bitand e) <%
        e.Output();
        return 1;
    %>

    return 0;
%>


这是友善之臂的CMOS摄像头的测试程序,是用C++实现的,
测试成功了,不过对于程序的原理还是不明白,比如在读取图像信息的时候需要设置哪些信息,
需要读取的缓冲区在哪等,希望高手指点,帮忙注视一下这个程序也行。谢谢!
级别: 新手上路
UID: 18577
精华: 0
发帖: 27
金钱: 135 两
威望: 27 点
综合积分: 54 分
注册时间: 2010-04-11
最后登录: 2016-04-24
1楼  发表于: 2010-05-31 17:30
我也求教
级别: 新手上路
UID: 25219
精华: 0
发帖: 3
金钱: 15 两
威望: 3 点
综合积分: 6 分
注册时间: 2010-07-21
最后登录: 2010-08-10
2楼  发表于: 2010-07-27 13:24
同请教
坚持,重复,总结就是成功
级别: 新手上路
UID: 22598
精华: 0
发帖: 23
金钱: 115 两
威望: 23 点
综合积分: 46 分
注册时间: 2010-06-03
最后登录: 2011-01-03
3楼  发表于: 2010-07-27 16:56
同求。。。截图是如何办到的?
级别: 新手上路
UID: 22187
精华: 0
发帖: 2
金钱: 10 两
威望: 2 点
综合积分: 4 分
注册时间: 2010-05-27
最后登录: 2010-09-20
4楼  发表于: 2010-09-11 10:47
改成这种形式应该容易懂了吧。

#include <iostream>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <linux/types.h>
#include <linux/fb.h>


class TError {
public:
    TError(const char *msg) {
        this->msg = msg;
    }
    TError(const TError & e) {
        msg = e.msg;
    }
    void Output() {
        std::cerr << msg << std::endl;
    }
    virtual ~TError() {}
protected:
    TError & operator=(const TError &);
private:
    const char *msg;
};

// Linear memory based image
class TRect {
public:
    TRect():  Addr(0), Size(0), Width(0), Height(0), LineLen(0), BPP(16) {
    }
    virtual ~TRect() {
    }
    bool DrawRect(const TRect & SrcRect, int x, int y) const {
        if (BPP != 16 || SrcRect.BPP != 16) {
            // don't support that yet
            throw TError("does not support other than 16 BPP yet");
        }

        // clip
        int x0, y0, x1, y1;
        x0 = x;
        y0 = y;
        x1 = x0 + SrcRect.Width - 1;
        y1 = y0 + SrcRect.Height - 1;
        if (x0 < 0) {
            x0 = 0;
        }
        if (x0 > Width - 1) {
            return true;
        }
        if( x1 < 0) {
            return true;
        }
        if (x1 > Width - 1) {
            x1 = Width - 1;
        }
        if (y0 < 0) {
            y0 = 0;
        }
        if (y0 > Height - 1) {
            return true;
        }
        if (y1 < 0) {
            return true;
        }
        if (y1 > Height - 1) {
            y1 = Height -1;
        }

        //copy
        int copyLineLen = (x1 + 1 - x0) * BPP / 8;
        unsigned char *DstPtr = Addr + LineLen * y0 + x0 * BPP / 8;
        const unsigned char *SrcPtr = SrcRect.Addr + SrcRect.LineLen *(y0 - y) + (x0 - x) * SrcRect.BPP / 8;

        for (int i = y0; i <= y1; i++) {
            memcpy(DstPtr, SrcPtr, copyLineLen);
            DstPtr += LineLen;
            SrcPtr += SrcRect.LineLen;
        }
        
        
        return true;
    }

    bool DrawRect(const TRect & rect) const { // default is Center
        return DrawRect(rect, (Width - rect.Width) / 2, (Height - rect.Height) / 2);
    }

    bool Clear() const {
        int i;
        unsigned char *ptr;
        for (i = 0, ptr = Addr; i < Height; i++, ptr += LineLen) {
            memset(ptr, 0, Width * BPP / 8);
        }
        return true;
    }

protected:
    TRect(const TRect &);
    TRect & operator=( const TRect &);

protected:
    unsigned char *Addr;
    int Size;
    int Width, Height, LineLen;
    unsigned BPP;
};



class TFrameBuffer: public TRect {
public:
    TFrameBuffer(const char *DeviceName = "/dev/fb0"): TRect(), fd(-1) {
        Addr = (unsigned char *)MAP_FAILED;

            fd = open(DeviceName, O_RDWR);
        if (fd < 0) {
            throw TError("cannot open frame buffer");
        }

            struct fb_fix_screeninfo Fix;
            struct fb_var_screeninfo Var;
        if (ioctl(fd, FBIOGET_FSCREENINFO, & Fix) < 0 || ioctl(fd, FBIOGET_VSCREENINFO, & Var) < 0) {
            throw TError("cannot get frame buffer information");
        }

        BPP = Var.bits_per_pixel;
            if (BPP != 16) {
            throw TError("support 16BPP frame buffer only");
        }

            Width  = Var.xres;
            Height = Var.yres;
            LineLen = Fix.line_length;
              Size = LineLen * Height;

        int PageSize = getpagesize();
        Size = (Size + PageSize - 1) / PageSize * PageSize ;
            Addr = (unsigned char *)mmap(NULL, Size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
        if (Addr == (unsigned char *)MAP_FAILED) {
            throw TError("map frame buffer failed");
            return;
        }
        ::close(fd);
        fd = -1;

        Clear();
    }

    virtual ~TFrameBuffer() {
        ::munmap(Addr, Size);
        Addr = (unsigned char *)MAP_FAILED;

        ::close(fd);
        fd = -1;
    }

protected:
    TFrameBuffer(const TFrameBuffer &);
    TFrameBuffer & operator=( const TFrameBuffer &);
private:
    int fd;
};

class TVideo : public TRect {
public:
    TVideo(const char *DeviceName = "/dev/camera"): TRect(), fd(-1) {
        Addr = 0;
        fd = ::open(DeviceName, O_RDONLY);
        if (fd < 0) {
            throw TError("cannot open video device");
        }
        Width = 320;
        Height = 240;
        BPP = 16;
        LineLen = Width * BPP / 8;
        Size = LineLen * Height;
        Addr = new unsigned char<:Size:>;

        Clear();
    }

    bool FetchPicture() const {
        int count = ::read(fd, Addr, Size);
        if (count != Size) {
            throw TError("error in fetching picture from video");
        }
        return true;
    }

    virtual ~TVideo() {
        ::close(fd);
        fd = -1;
        delete<::> Addr;
        Addr = 0;
    }

protected:
    TVideo(const TVideo &);
    TVideo & operator=(const TVideo &);

private:
    int fd;
};

int main(int argc, char **argv)
{
    try {
        TFrameBuffer FrameBuffer;
        TVideo Video;
        for (;;) {
            Video.FetchPicture();
            FrameBuffer.DrawRect(Video);
        }
    } catch (TError & e) {
        e.Output();
        return 1;
    }

    return 0;
}
级别: 新手上路
UID: 35134
精华: 0
发帖: 15
金钱: 80 两
威望: 16 点
综合积分: 30 分
注册时间: 2010-12-27
最后登录: 2018-04-19
5楼  发表于: 2010-12-27 14:09
这个程序在提供的源码哪个位置啊?
ARM9
级别: 新手上路
UID: 12600
精华: 0
发帖: 26
金钱: 140 两
威望: 28 点
综合积分: 52 分
注册时间: 2010-01-10
最后登录: 2011-11-04
6楼  发表于: 2011-03-14 08:52
这个问题已经解决了,我这有做好的C程序
级别: 新手上路
UID: 50331
精华: 0
发帖: 20
金钱: 100 两
威望: 20 点
综合积分: 40 分
注册时间: 2011-06-21
最后登录: 2012-11-05
7楼  发表于: 2011-07-10 15:17

 回 6楼(wuquan-1203) 的帖子

在\linux-2.6.29\examples\camtest目录下

提供的代码为什么有<%%>,2楼的回答似乎这就是{},不明白?
级别: 新手上路
UID: 50331
精华: 0
发帖: 20
金钱: 100 两
威望: 20 点
综合积分: 40 分
注册时间: 2011-06-21
最后登录: 2012-11-05
8楼  发表于: 2011-07-10 15:29

 回 6楼(wuquan-1203) 的帖子

做好了,就分享一下你的C程序啊
级别: 新手上路
UID: 53868
精华: 0
发帖: 12
金钱: 70 两
威望: 14 点
综合积分: 24 分
注册时间: 2011-08-18
最后登录: 2014-04-01
9楼  发表于: 2011-09-06 10:38
友善提供的只是个字符设备驱动而已,数据格式RGB565,自动曝光,参数都不可控,只能做视频,基本没啥用
  • «
  • 1
  • 2
  • »
  • Pages: 1/2     Go