⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blobtracker.cpp

📁 guide and some example with visualC++
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // Search the frame for bright spots.    BlobTrackerObjectList new_objects;    FindObjects(new_objects);    // Match up the objects just found with the ones found previously,    // to try to achieve continuity of object ids across frames.    BlobTrackerObjectList old_objects = *m_objects;    m_objects->clear();    unsigned long matched = 0;    for (BlobTrackerObjectList::iterator old = old_objects.begin(); old != old_objects.end(); )    {        int min_d = m_distance_threshold;        BlobTrackerObjectList::iterator min_o = new_objects.end();        for (BlobTrackerObjectList::iterator o = new_objects.begin(); o != new_objects.end(); o++)        {            if (InRect(old->GetRect(), o->GetCenter()))            {                min_o = o;                break;            }            int d = distance(o->GetCenter(), old->GetCenter());            if (d < min_d)            {                min_d = d;                min_o = o;            }        }        if (min_o != new_objects.end())        {            int id = old->GetId();            min_o->SetId(id);            matched |= 1 << id;            m_objects->push_back(*min_o);            new_objects.erase(min_o);            old_objects.erase(old);        }        else        {            old++;        }    }    // For any objects that weren't matched up, assign ids in    // order of decreasing size.    if (m_objects->size() < m_num_objects && new_objects.size() > 0)    {        std::sort(new_objects.begin(), new_objects.end(), size_cmp);        int id = 0;        for (BlobTrackerObjectList::iterator o = new_objects.begin();             o != new_objects.end() && m_objects->size() < m_num_objects;             o++)        {            while (matched & (1 << id))                id++;            o->SetId(id);            id++;            m_objects->push_back(*o);        }    }    // Generate output frame    FillDestinationData(image);    return NOERROR;}// (These functions are not very efficient, but they are called rarely enough// that it is not a big impact on performance.)static inline int GetPixel(const unsigned char *image, int width, int x, int y){    return image[y*width + x];}static inline void SetPixel(unsigned char *image, int width, int x, int y, int color){    image[y*width + x] = color;}// Search the image for spots that meet the brightness and size thresholds.void BlobTracker::FindObjects(BlobTrackerObjectList &objects){    for (int y = 0; y < m_image_format.height; y++)    {        for (int x = 0; x < m_image_format.width; x++)        {            // Check each pixel to see if it meets the brightness threshold.            // (This call to GetPixel is the only one that is executed with enough frequency to have            // any impact on performance, but optimizing it gave minimal performance improvement.)            if (GetPixel((unsigned char *)m_image->imageData, m_image_format.width, x, y) >= m_pixel_threshold)            {                // Find all connected bright pixels. Set them all to black while keeping track                // of the bounding rectangle and the number of pixels found.                CvRect rect;                int area;                FloodFill((unsigned char *)m_image->imageData, m_image_format.width, m_image_format.height, x, y, m_pixel_threshold, rect, area);                // Ignore any spots that don't meet the size threshold.                if (area >= m_size_threshold)                    objects.push_back(BlobTrackerObject(rect, area));            }        }    }}// Filled horizontal segment of scanline y for xl$<=$x$<=$xr.// Parent segment was on line y-dy. dy=l or -1struct Segment {    int y, xl, xr, dy;    Segment(int a, int b, int c, int d) : y(a), xl(b), xr(c), dy(d) { };};static inline void push(std::stack<Segment> &stack, int height, int y, int xl, int xr, int dy){    y += dy;    if (y >= 0 && y < height)        stack.push(Segment(y, xl, xr, dy));}static inline void SetPixel(unsigned char *image, int width, int x, int y, int color, CvRect &rect, int &area){    if (x < rect.x)        rect.x = x;    else if (x >= rect.x+rect.width)        rect.width = x+1-rect.x;    if (y < rect.y)        rect.y = y;    else if (y >= rect.y+rect.height)        rect.height = y+1-rect.y;    SetPixel(image, width, x, y, color);    area++;}#define GET_PIXEL(x, y) GetPixel(image, width, x, y)#define SET_PIXEL(x, y) SetPixel(image, width, x, y, 0, rect, area)#define PUSH(y, xl, xr, dy) push(stack, height, y, xl, xr, dy)// FloodFill: set the pixel at (x,y) and all of its 4-connected neighbors// that meet the brightness threshold to zero while keeping track// of the bounding rectangle and the number of pixels found.// A 4-connected neighbor is a pixel above, below, left, or right of// a pixel.// Algorithm adapted from one by Paul Heckbert 13 Sept 1982, 28 Jan 1987.static void FloodFill(unsigned char *image, int width, int height, int start_x, int start_y, int threshold, CvRect &rect, int &area){    CvRect init_rect = { start_x, start_y, 1, 1 };    rect = init_rect;    area = 0;    std::stack<Segment> stack;    PUSH(start_y, start_x, start_x, 1); /* needed in some cases */    PUSH(start_y+1, start_x, start_x, -1); /* seed segment (popped 1st) */    while (!stack.empty())    {        /* pop segment off stack and fill a neighboring scan line */        const Segment seg = stack.top();        stack.pop();        // segment of scan line y-dy for xl<=x<=x2 was        // previously filled,        // now explore adjacent pixels in scan line y        int l;        int x;        for (x = seg.xl; x >= 0 && GET_PIXEL(x, seg.y) >= threshold; x--)            SET_PIXEL(x, seg.y);        if (x >= seg.xl)            goto skip;        l = x+1;        if (l < seg.xl)            PUSH(seg.y, l, seg.xl-1, -seg.dy); /* leak on left? */        x = seg.xl+1;        do {            for (; x < width && GET_PIXEL(x, seg.y) >= threshold; x++)                SET_PIXEL(x, seg.y);            PUSH(seg.y, l, x-1, seg.dy);            if (x > seg.xr+1)                PUSH(seg.y, seg.xr+1, x-1, -seg.dy); /* leak on right? */skip:            for (x++; x <= seg.xr && GET_PIXEL(x, seg.y) < threshold; x++)                ;            l = x;        } while (x <= seg.xr);    }}// Registration information// List of class IDs and creator functions for the class factory. This// provides the link between the COM entry point in the DLL and an object// being created. The class factory will call the static CreateInstance.CFactoryTemplate g_Templates[] = {    { L"Blob Tracker", &CLSID_BlobTracker, BlobTracker::CreateInstance },    { L"Blob Tracker Property Page", &CLSID_BlobTrackerPropertyPage, BlobTrackerPropertyPage::CreateInstance }};int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);//// DllRegisterServer//// Register the COM objects (the tracker and the property page).// Also add the tracker to the "Video Trackers" component category.STDAPI DllRegisterServer(){    HRESULT hr = AMovieDllRegisterServer2( TRUE );    if (FAILED(hr))        return hr;    ICatRegister *reg;    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatRegister, (void **)&reg);    if (FAILED(hr))        return hr;    CATEGORYINFO catinfo;    catinfo.catid = CATID_Trackers;    catinfo.lcid = 0x409;    wcscpy(catinfo.szDescription, L"Video Trackers");    reg->RegisterCategories(1, &catinfo);    reg->RegisterClassImplCategories(CLSID_BlobTracker, 1, const_cast<GUID *>(&CATID_Trackers));    reg->Release();    return NOERROR;} // DllRegisterServer//// DllUnregisterServer//// Unregister the COM objects (the tracker and the property page).// Also remove the tracker from the "Video Trackers" component category.STDAPI DllUnregisterServer(){    HRESULT hr = AMovieDllRegisterServer2( FALSE );    if (FAILED(hr))        return hr;    ICatRegister *reg;    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatRegister, (void **)&reg);    if (FAILED(hr))        return hr;    reg->UnRegisterClassImplCategories(CLSID_BlobTracker, 1, const_cast<GUID *>(&CATID_Trackers));    reg->Release();    return NOERROR;} // DllUnregisterServer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -