LINUX.ORG.RU

Разница между изображениями

 


0

2

Добрый день! Есть 2 изображения с видеокамеры. Первое базовое, второе базовое с неким объектом на нем. Как без каких-либо нейросетей выянить насколько 1 и 2 изображение отличаются? То есть, например если два кадра одинаковые (или несущественно отличаются) или два кадра сильно отличаются - базовое изображение и базовое с авто на нем?

Можно ли реализовать что-то такое на openCV ? какая точность? Есть ли какое-то решение через евклидово расстояние?

★★

Последнее исправление: Andreezy (всего исправлений: 1)

Безо всяких сложных библиотек можно тупо считать попиксельную разницу и как-то агрегировать. Работает вполне норм если у тебя задача просто сравнить и всё.

firkax ★★★★★
()

Можно ли реализовать что-то такое на openCV ? какая точность? Есть ли какое-то решение через евклидово расстояние?

а вы пробовали ?

точнее даже так - в что вы пробовали ??

потому-что для OpenCV это буквально цитирование мануалов.. и наверняка для ffmpeg тоже. И для gstreamer..и пол-интернета завалено взаимными копи-пастами про такое

MKuznetsov ★★★★★
()

Да можно реализовать без ИИ. Такое уже есть. Смотри темы про организацию наблюдения помню пакет моушн, скрипты и имаджмеджик.

Enter
()
Ответ на: комментарий от anonymous

Вот это подходит отлично. Спасибо

Andreezy ★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Просто по приколу, самый примитив, модифицированное вот это Gray > Red/Blue (тепловизор) (комментарий)

dron@gnu:~/Рабочий-стол/compare$ gcc main.c 
dron@gnu:~/Рабочий-стол/compare$ ./a.out 1.tga 2.tga 3.tga
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

struct image
{
    uint16_t size_x;
    uint16_t size_y;
    uint8_t *image;
    uint8_t *image_data;
};

struct color
{
    uint8_t r;
    uint8_t g;
    uint8_t b;
    uint8_t a;
};

enum chanel
{
    R,G,B,A
};

struct image * load_image(const char * filename)
{
    FILE * file = fopen(filename,"r");
    if(!file)
    {
        fprintf(stderr,"Filed open file '%s' %s:%d\n",filename,__FILE__,__LINE__);
        return NULL;
    }

    fseek(file,0,SEEK_END);
    long file_len= ftell(file);
    fseek(file,0,SEEK_SET);

    uint8_t * imagex = malloc(sizeof(uint8_t) * file_len);
    if(!imagex)
    {
        fprintf(stderr,"Filed allocate memm '%s' %s:%d\n",filename,__FILE__,__LINE__);
        fclose(file);
        return NULL;
    }

    size_t read_len = fread(imagex,file_len,1,file);
    if(!read_len)
    {
        fprintf(stderr,"File is empty '%s' %s:%d\n",filename,__FILE__,__LINE__);
        fclose(file);
        free(imagex);
        return NULL;
    }

    uint16_t width, height = 0;
    char footer = 0;
    char header = 18;
    char depth  = 0;
    char descriptor = 0;
    char true_color_type = 0;
    const char true_color_rle = 10;
    const char true_color_no_rle = 2;

    true_color_type = imagex[2];
    width = *(uint16_t*)(imagex+12);
    height= *(uint16_t*)(imagex+14);
    depth = imagex[16];
    descriptor = imagex[17];
    int start_coord = (descriptor  >> 5) & 1u;

    if(true_color_type == true_color_rle )
    {
        fprintf(stderr,"No support RLE compress%s:%d",__FILE__,__LINE__);
        fclose(file);
        free(imagex);
        return NULL;
    }

    struct image * img = malloc(sizeof(struct image));

    if(!img)
    {
        fprintf(stderr,"Filed allocate memm '%s' %s:%d\n",filename,__FILE__,__LINE__);
        fclose(file);
        free(imagex);
        return NULL;
    }

    img->size_x = width;
    img->size_y = height;
    img->image  = imagex;
    img->image_data = imagex+header;
    fclose(file);
    return img;
}

void save_image(struct image * img,const char * filename)
{
   unsigned char y = img->size_y;
   unsigned char xa= img->size_x % 256;
   unsigned char xb= (img->size_x-xa)/256;
   unsigned char ya= img->size_y % 256;
   unsigned char yb= (img->size_y-ya)/256;
   unsigned char header[18] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, xa, xb, ya, yb, 32, 0};
   FILE * file = fopen(filename, "wb");
   fwrite(header,1, sizeof(header), file);
   fwrite(img->image_data,1, img->size_x * img->size_y * 4, file);
}

struct coord
{
    int min_x;
    int max_x;
    int min_y;
    int max_y;
};

struct coord diff_image(struct image * imga,struct image * imgb )
{
    printf("%d %d %d %d\n",imga->size_x,imga->size_y,imgb->size_x,imgb->size_y);

    if(imga->size_x != imgb->size_x || imga->size_y != imgb->size_y)
    {
       return (struct coord){-1,-1,-1,-1};
    }

    struct coord c =
    {
        .min_x = 0,
        .max_x = imga->size_x,
        .min_y = 0,
        .max_y = imga->size_y,
    };

    for (int yy = 0;  yy < imga->size_y; ++yy){
    for (int xx = 0;  xx < imga->size_x; ++xx)
    {
       if(((int)((float)imga->image_data[xx * 4 + yy * imga->size_x * 4 + 0] * 0.33 +
                 (float)imga->image_data[xx * 4 + yy * imga->size_x * 4 + 1] * 0.33 +
                 (float)imga->image_data[xx * 4 + yy * imga->size_x * 4 + 2] * 0.33)) ==
          ((int)((float)imgb->image_data[xx * 4 + yy * imgb->size_x * 4 + 0] * 0.33 +
                 (float)imgb->image_data[xx * 4 + yy * imgb->size_x * 4 + 1] * 0.33 +
                 (float)imgb->image_data[xx * 4 + yy * imgb->size_x * 4 + 2] * 0.33)))
       {
            if(c.min_x < xx && c.max_x > xx)
            {
                c.min_x = xx;
            }
            if(c.min_x > xx && c.max_x < xx)
            {
                c.max_x = xx;
            }
            if(c.min_y < yy && c.max_y > yy)
            {
                c.min_y = yy;
            }
            if(c.min_y > yy && c.max_y < yy)
            {
                c.max_y = yy;
            }
            imgb->image_data[xx * 4 + yy * imgb->size_x * 4 + 0] = 0;
            imgb->image_data[xx * 4 + yy * imgb->size_x * 4 + 1] = 0;
            imgb->image_data[xx * 4 + yy * imgb->size_x * 4 + 2] = 0;

       }

    }}

    return c;
}

int main(int argc, char *argv[])
{
   struct image * imga = NULL;
   struct image * imgb = NULL;

   imga = load_image(argv[1]);
   imgb = load_image(argv[2]);
   diff_image(imga,imgb);
   save_image(imgb,argv[3]);

   return 0;
}
LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от firkax

попиксельно плохо, слишком много шума из за освещенности например, нужно разбивать изображение на участки и их и сравнивать с коэффициентом несовпадения.

anonymous2 ★★★★★
()

Я уже писал для сравнения изображений, даже с несколькими вариантами, вот тут финальный код: https://notabug.org/bfgeshka/picunic/src/master/src/hashing.c#L96

Общий подход:

  1. Квантуем.

  2. Грейскейлим.

  3. Сравниваем изменение яркости пикселя с соседним.

Bfgeshka ★★★★★
()
Последнее исправление: Bfgeshka (всего исправлений: 1)
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.