ViBe - рдкреГрд╖реНрдарднреВрдорд┐ рдШрдЯрд╛рд╡ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо

рдкреНрд░рд╛рдЧрд┐рддрд┐рд╣рд╛рд╕

рдХреБрдЫ рд╕рд╛рд▓ рдкрд╣рд▓реЗ, рдЪрд▓рддреА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдЖрд╡рдВрдЯрди рдФрд░ рдЯреНрд░реИрдХрд┐рдВрдЧ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рджреМрд░рд╛рди, рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкреГрд╖реНрдарднреВрдорд┐ рдШрдЯрд╛рд╡ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рджреЗрдЦреЗ рдЧрдП рдереЗ, рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреА рдмрд╛рдж рдореЗрдВ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдореЗрдВ рд╕реЗ рдПрдХ рдирд┐рдХрд▓рд╛ред рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рджреЛрд╖ рдкреЗрдЯреЗрдВрдЯ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдпрд╣ рд╕рдВрд░рдХреНрд╖рд┐рдд рд╣реИред рд▓реЗрдХрд┐рди рдирд┐рд╕реНрд╕рдВрджреЗрд╣ рд▓рд╛рднреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╣реИ, рдЬрд┐рд╕реЗ рдЧреИрд░-рд╡рд╛рдгрд┐рдЬреНрдпрд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИред рдЗрд╕рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рдкреГрд╖реНрда рдкрд░ рдЖрдк рдЗрд╕реЗ рдмрд╣реБрдд рд╣реА рдкреБрд╕реНрддрдХрд╛рд▓рдп, рд╕рд╛рде рд╣реА рд╡рд┐рдВрдбреЛрдЬ рдФрд░ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд▓рд┐рдП рдбреЗрдореЛ-рдкреНрд░реЛрдЧреНрд░рд╛рдо, рдкреЗрдЯреЗрдВрдЯ рдХреЗ рд▓рд┐рдВрдХ (рдЬрд╣рд╛рдВ рдЖрдк рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдореВрд▓ рд╡рд┐рд╡рд░рдг рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ) рдФрд░ рдЕрдиреНрдп рд░реЛрдЪрдХ рдЬрд╛рдирдХрд╛рд░реА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рдЫрд╡рд┐

рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рд╕реНрдХреЗрд▓ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП:
#include "vibe-background.h" int main(int argc, char **argv){ //   ViBe vibeModel_t *model = libvibeModelNew(); // stride -  ,     uint8_t *image_data = acquire_image(stream); int32_t width = get_image_width(stream); int32_t height = get_image_height(stream); int32_t stride = get_image_stride(stream); //     uint8_t *segmentation_map = malloc(stride * height); //     libvibeModelAllocInit_8u_C1R(model, image_data, width, height, stride); //     //   -  segmentation_map while(!finished(stream)){ image_data = acquire_image(stream); libvibeModelUpdate_8u_C1R(model, image_data, segmentation_map); } //   libvibeModelFree(model); } 


рдЙрд╕рдХреА рдЬрд┐рдж

рдЕрдЧрд▓рд╛ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛ред рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд╕реНрд░реЛрдд рдкрд╛рда рдХреЛ рдирд╣реАрдВ рджрд┐рдЦрд╛рдпрд╛, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдкреЗрдЯреЗрдВрдЯ, рдПрдЪ - рдлрд╛рдЗрд▓ рдФрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рд╡рд┐рд╡рд░рдг рд╣реИ, рддреЛ рд░рд╛рдд рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдФрд░ рдХрдИ рд▓реАрдЯрд░ рдХреЙрдлреА рдЗрд╕реЗ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИрдВред
рддреЛ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

VibeModel_t рд╕рдВрд░рдЪрдирд╛:
 typedef struct { u8b *samples; u32b numberOfSamples; u32b sizeOfSample; } pixel; typedef struct { pixel *pixels; u32b width; u32b height; u32b stride; u32b numberOfSamples; u32b matchingThreshold; u32b matchingNumber; u32b updateFactor; } vibeModel; typedef vibeModel vibeModel_t; 


рдпрд╣рд╛рдВ рдХреНрдпреЛрдВ рд╣реИ - рдпрд╣ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рд╕реЗ рдЖрдЧреЗ рд╕рдордЭрд╛ рдЬрд╛рдПрдЧрд╛ред
рдПрдХ рдореЙрдбрд▓ рдмрдирд╛рдПрдВ, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЖрд░рдВрдн рдХрд░реЗрдВред

 vibeModel *libvibeModelNew() { vibeModel *model = (vibeModel*)calloc(1,sizeof(vibeModel)); if (model) { model->numberOfSamples = 20; model->matchingThreshold = 20; model->matchingNumber = 2; model->updateFactor = 16; } u32b seed = time(0); srand(seed); return model; } 


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣рд╛рдВ рдХреЛрдб рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдирд╣реАрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рд╣реИ
 u32b getRandPixel(const u8b *image_data, const u32b width, const u32b height, const u32b stride, const u32b x, const u32b y); 

рдЬреЛ [xy] рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рдмреЗрддрд░рддреАрдм рдврдВрдЧ рд╕реЗ рдЪрдпрдирд┐рдд рдкрд┐рдХреНрд╕реЗрд▓ рдХрд╛ рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред рддрдм рдореЙрдбрд▓ рдХрд╛ рдЖрд░рдВрдн рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 s32b libvibeModelAllocInit_8u_C1R(vibeModel *model, const u8b *image_data, const u32b width, const u32b height, const u32b stride) { if (!model || !image_data || !width || !height || !stride || (stride<width)) return 1; //    model->width = width; model->height = height; model->stride = stride; //      model->pixels = 0; model->pixels = (pixel*)calloc(model->width*model->height, sizeof(pixel)); if (!model->pixels) return 1; //          . for (u32b i=0; i < model->width*model->height; i++) { model->pixels[i].numberOfSamples=model->numberOfSamples; model->pixels[i].sizeOfSample = 1; model->pixels[i].samples = 0; model->pixels[i].samples = (u8b*)calloc(model->numberOfSamples,sizeof(u8b)); if (!model->pixels[i].samples) return 1; } //  . //   .           , //       . u32b n=0; for (u32b j=0; j < model->height; j++) { for (u32b i=0; i < model->width; i++) { model->pixels[n].samples[0] = image_data[i+j*stride]; for (u32b k=1; k < model->numberOfSamples; k++) model->pixels[n].samples[k] = getRandPixel(image_data, width, height, stride, i, j); n++; } } return 0; } 


рдореЙрдбрд▓ рддреИрдпрд╛рд░ рд╣реИред LibvibeModelAllocInit_8u_C3R рдлрд╝рдВрдХреНрд╢рди рдХреА рд╕рдВрд░рдЪрдирд╛ рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдкреНрд░рддреНрдпреЗрдХ рдирдореВрдиреЗ рдореЗрдВ рдПрдХ рдмрд╛рдЗрдЯ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рддреАрди рд╣реИрдВред
рдЗрд╕рдХреЗ рдмрд╛рдж рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдХрд╛ рд╕рдмрдЯреНрд░реЗрдХреНрд╢рди рдФрд░ рдЙрд╕рдХреЗ рдореЙрдбрд▓ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЖрддрд╛ рд╣реИред рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдХреА рдкреГрд╖реНрдарднреВрдорд┐ рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдпрд╣ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 // pix_data -   // pixel -     vibeModel s32b comparePixel(u8b pix_data, pixel *pixel, u32b matchingThreshold, u32b matchingNumber) { u32b matchingCounter=0; //     for (u32b i=0; i<pixel->numberOfSamples; i++) { if (abs((s32b)pix_data-(s32b)pixel->samples[i]) < matchingThreshold) { //         MatchingNumber, //  ,         matchingCounter++; if (matchingCounter >= matchingNumber) return 1; } } return 0; } 


рдЕрднреА рднреА рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдХреА рдЬрд░реВрд░рдд рд╣реИ
 updateModel(vibeModel *model, u8b pix_data, u32b width, u32b height, u32b stride, u32b x, u32b y); 

рдЬреЛ, getRandPixel (...) рдХреА рддрд░рд╣ рд▓рдВрдмрд╛ рдФрд░ рд╕рд░рд▓ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдХреЛрдб рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ред рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд░рддрд╛ рд╣реИ: рдЬрдм 1 / рдореЙрдбрд▓-> рдЕрдкрдбреЗрдЯрдлреИрдХреНрдЯрд░ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдкрд┐рдХреНрд╕реЗрд▓ рдореЙрдбрд▓ [x, y] рдХреЗ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд░реВрдк рд╕реЗ рдЪрдпрдирд┐рдд рдирдореВрдиреЗ рдХреЗ рд▓рд┐рдП pix_data рдХрд╛ рдорд╛рди рд▓рд┐рдЦрддрд╛ рд╣реИ, рдФрд░ рдкрд╛рд╕ рдХреЗ рдкрд┐рдХреНрд╕реЗрд▓ (рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рднреА) рдХреЗ рдирдореВрдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рд▓рд┐рдПред

рдФрд░ рдЕрдВрдд рдореЗрдВ, рдореБрдЦреНрдп рдХрд╛рд░реНрдп:

 s32b libvibeModelUpdate_8u_C1R(vibeModel *model, const u8b *image_data, u8b *segmentation_map) { s32b ad = model->stride - model->width; if (!model || !image_data || !segmentation_map) return 1; if (model->stride < model->width) return 1; u32b n=0; for (u32b j=0; j < model->height; j++) { for (u32b i=0; i < model->width; i++) { //      if (comparePixel(image_data[n], &(model->pixels[n]), model->matchingThreshold, model->matchingNumber)) { //    -      segmentation_map[n] = 0; updateModel(model, image_data[n], model->width, model->height, model->stride,i,j); } else { //    segmentation_map[n] = 0xFFU; } n++; } if (model->stride > model->width) n+=ad; } return 0; } 

LibvibeModelUpdate_8u_C3R рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рдлрд┐рд░ рд╕реЗ рд╕рдорд╛рди рд╣реИред

рд╕рд╛рдорд╛рдиреНрдп рдЗрдВрдкреНрд░реЗрд╢рди

рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛рдлреА рд╕рд░рд▓ рдФрд░ рд╕рдмрд╕реЗ рддреЗрдЬрд╝ рдирд┐рдХрд▓рд╛, рдЬрд┐рдирдореЗрдВ рд╕реЗ рд╣рдо рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ (рдкреГрд╖реНрдарднреВрдорд┐ рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рдХреБрдЫ рдЕрдиреБрдХреВрд▓рдирд╢реАрд▓рддрд╛ рдФрд░ рдЗрд╕рдХреЗ рдХреНрд░рдорд┐рдХ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд╕рд╛рде рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рдмреАрдЪ)ред рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпрдХреНрд░рдо рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рднреА рдПрд╡реАрдЖрдИрдПрдЪрд╣рдХрд╛ рдкрд░ рдЗрд╕рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред

Source: https://habr.com/ru/post/In165677/


All Articles