started to work on detection and filter

test16bit
Steffen Pohle 4 years ago
parent 295e0fa6af
commit 605e81389e

@ -0,0 +1,160 @@
#include <unistd.h>
#include "config.h"
#include "gui.h"
#include "filter.h"
extern Filter filter;
gboolean cb_filtertemp_thread (gpointer data);
gboolean cb_filterout_thread (gpointer data);
//
// C / C++ Wrapper for the thread function
//
gpointer _FilterThread (gpointer data) {
filter.Thread ();
return NULL;
};
Filter::Filter() { // @suppress("Class members should be properly initialized")
g_mutex_init (&mutexin);
g_mutex_init (&mutexout);
g_mutex_init (&mutextmp);
g_mutex_init (&mutex);
running = 1;
inFrame.SetSize(64, 64);
oldFrame.SetSize(64, 64);
temp.SetSize(64, 64);
tempgtk.SetSize(64, 64);
image.SetSize(64, 64);
imagegtk.SetSize(64, 64);
thread = NULL;
thread = g_thread_new("Filter", _FilterThread, NULL);
};
Filter::~Filter() {
running = 0;
if (thread) {
g_thread_join (thread);
thread = NULL;
}
};
int Filter::NewFrame(VideoFrame *newframe) {
LockInMutex();
inFrame.CopyFrom(newframe);
inFrameNew = 1;
UnLockInMutex();
return -1;
};
//
// NewFrame: will set new frame
// Thread: newFrame |------> Find Object --- not found ---> send gui information
void Filter::Thread() {
while (running) {
// check for new frame
LockInMutex();
if (inFrameNew == 1) {
inFrameNew = 0;
//
// do some input detection improvement
InputDetect();
oldFrame.CopyFrom(&inFrame);
UnLockInMutex();
// copy temporary image for gtk
LockTempMutex();
tempgtk.CopyFrom(&temp);
UnLockTempMutex();
gdk_threads_add_idle(cb_filtertemp_thread , &tempgtk);
//
// do some other stuff use if possible only the oldFrame data
ComposeOutput();
// copy output image for gtk
LockOutMutex();
imagegtk.CopyFrom(&image);
UnLockOutMutex();
gdk_threads_add_idle(cb_filterout_thread , &imagegtk);
}
else
UnLockInMutex();
usleep (10000);
}
}
void Filter::InputDetect() {
int x, y;
float vo, v;
unsigned char *pxs, *pxso, *pxstemp;
unsigned char pixel;
int idx;
FloatImage fi;;
float fmin, fmax;
temp.SetSize (inFrame.w, inFrame.h);
fi.SetSize (inFrame.w, inFrame.h);
pxs = inFrame.data;
pxso = oldFrame.data;
pxstemp = temp.data;
for (x = 0; x < temp.w && x < inFrame.w && x < oldFrame.w; x++)
for (y = 0; y < temp.h && y < inFrame.h && y < oldFrame.h; y++) {
idx = (inFrame.w * y + x);
vo = pxso[3*idx+0] + pxso[3*idx+1] + pxso[3*idx+2];
v = pxs[3*idx+0] + pxs[3*idx+1] + pxs[3*idx+2];
fi.data[idx] = v - vo;
if (idx == 0 || fmin > fi.data[idx]) fmin = fi.data[idx];
if (idx == 0 || fmax < fi.data[idx]) fmax = fi.data[idx];
}
for (x = 0; x < temp.w && x < inFrame.w && x < oldFrame.w; x++)
for (y = 0; y < temp.h && y < inFrame.h && y < oldFrame.h; y++) {
idx = (inFrame.w * y + x);
pixel = (unsigned char)((float)( (fi.data[idx]-fmin) / (fmax-fmin)) * 256.0);
pxstemp[3*idx+0] = pixel;
pxstemp[3*idx+1] = pixel;
pxstemp[3*idx+2] = pixel;
}
}
#define FACTOR 100.0
void Filter::ComposeOutput() {
int x, y, idx, i;
float *pixd; // destination
unsigned char *pixs; // source
image.SetSize(oldFrame.w, oldFrame.h);
pixd = image.data;
pixs = oldFrame.data;
for (x = 0; x < temp.w && x < inFrame.w && x < oldFrame.w; x++)
for (y = 0; y < temp.h && y < inFrame.h && y < oldFrame.h; y++) {
idx = 3 * (oldFrame.w * y + x);
for (i = 0; i < 3; i++)
pixd[idx+i] = (FACTOR * pixd[idx+i]/FACTOR) + (pixs[idx+i] / FACTOR);
}
}

@ -0,0 +1,74 @@
/***************************************************************************************
*
* filter.h is part of SimpleSkyCam.
*
*****************************************************************************************/
#ifndef _FILTER_H_
#define _FILTER_H_
#include "gui.h"
#include "config.h"
#include "video.h"
#include "videoframe.h"
class Filter {
private:
int running;
VideoFrame inFrame; // input frame
int inFrameNew; // new input frame;
VideoFrame oldFrame; // oldinput frame
VideoFrame temp; // temporary image
VideoFrame tempgtk; // temp image for gtk
FloatImage image; // output image
VideoFrame imagegtk; // output image -- send to gtk
GMutex mutexout;
GMutex mutexin;
GMutex mutextmp; // for access the temp image
GMutex mutex; // general mutex for changing settings
GThread *thread;
int objectW; // object Image Size Width
int objectH; // object Image Size Height
float *fpixels; //
void InputDetect();
void ComposeOutput();
public:
Filter();
~Filter();
int NewFrame (VideoFrame *newframe);
//
// Thread Releated Functions (maybe soon private?)
int TryLockInMutex() { return g_mutex_trylock(&mutextmp); };
void LockInMutex() { g_mutex_lock(&mutextmp);};
void UnLockInMutex() { g_mutex_unlock(&mutextmp);};
int TryLockTempMutex() { return g_mutex_trylock(&mutextmp); };
void LockTempMutex() { g_mutex_lock(&mutextmp);};
void UnLockTempMutex() { g_mutex_unlock(&mutextmp);};
int TryLockOutMutex() { return g_mutex_trylock(&mutexout); };
void LockOutMutex() { g_mutex_lock(&mutexout);};
void UnLockOutMutex() { g_mutex_unlock(&mutexout);};
void LockMutex() { g_mutex_lock(&mutex);};
void UnLockMutex() { g_mutex_unlock(&mutex);};
//
// Object functions
void SetObjectSize (int neww, int newh);
void SetObject (VideoFrame objFrame, int newx, int newy);
void GetObjectPos (int *x, int *y);
void Thread();
};
#endif

@ -0,0 +1,142 @@
#include "video.h"
#include "config.h"
#include "gui.h"
#define VIDEOFRAME_DEPTH_BYTES 3
VideoFrame::VideoFrame() {
data = NULL;
w = 0;
h = 0;
size = 0;
};
VideoFrame::~VideoFrame() {
if (data) {
free (data);
data = NULL;
}
w = 0;
h = 0;
size = 0;
};
//
// we will only allocate a new image if the needed size increases
void VideoFrame::SetSize(int nw, int nh) {
uint32_t newsize = VIDEOFRAME_DEPTH_BYTES * h * w;
if (newsize > size || data == NULL) {
unsigned char *newdata = (unsigned char *) malloc (newsize);
if (data != NULL) free (data);
data = newdata;
size = newsize;
}
w = nw;
h = nh;
};
VideoFrame VideoFrame::operator=(VideoFrame rightside) {
w = rightside.w;
h = rightside.h;
size = rightside.size;
if (size > 0) data = (unsigned char *) malloc (rightside.size);
if (rightside.data != NULL && size > 0) {
memcpy (data, rightside.data, size);
}
return *this;
}
void VideoFrame::CopyFrom(VideoFrame *source) {
SetSize (source->w, source->h);
memcpy(data, source->data, VIDEOFRAME_DEPTH_BYTES * w * h);
}
void VideoFrame::CopyFrom(FloatImage *source) {
float min, max;
int x, y, i, idx;
unsigned char v;
SetSize (source->w, source->h);
// find min max;
min = source->data[0];
max = source->data[0];
for (y = 0; y < h; y++) for (x = 0; x < w; x++)
for (i = 0; i < 3; i++) {
idx = 3 * (y * w + x);
if (min > source->data[idx+i]) min = source->data[idx+i];
if (max < source->data[idx+i]) max = source->data[idx+i];
}
for (y = 0; y < h; y++) for (x = 0; x < w; x++)
for (i = 0; i < 3; i++) {
idx = 3 * (y * w + x);
v = (float)(256.0 * (source->data[idx+i]-min) / (max-min));
}
}
FloatImage::FloatImage() {
data = NULL;
w = 0;
h = 0;
size = 0;
};
FloatImage::~FloatImage() {
if (data) {
free (data);
data = NULL;
}
w = 0;
h = 0;
size = 0;
};
//
// we will only allocate a new image if the needed size increases
void FloatImage::SetSize(int nw, int nh) {
uint32_t newsize = 3 * h * w * sizeof(float);
if (newsize > size || data == NULL) {
float *newdata = (float *) malloc (newsize);
if (data != NULL) free (data);
data = newdata;
size = newsize;
}
w = nw;
h = nh;
};
FloatImage FloatImage::operator=(FloatImage rightside) {
w = rightside.w;
h = rightside.h;
size = rightside.size;
if (size > 0) data = (float *) malloc (rightside.size);
if (rightside.data != NULL && size > 0) {
memcpy (data, rightside.data, size);
}
return *this;
}
void FloatImage::CopyFrom(FloatImage *source) {
SetSize (source->w, source->h);
memcpy(data, source->data, 3 * w * h);
}

@ -0,0 +1,51 @@
#ifndef _VIDEOFRAME_H_
#define _VIDEOFRAME_H_
#include "gui.h"
#include "config.h"
class FloatImage {
public:
int w;
int h;
uint32_t size;
float *data;
FloatImage();
~FloatImage();
FloatImage operator=(FloatImage rightside);
void SetSize(int nw, int nh);
void SetW(int nw) { SetSize(nw, h); };
void SetH(int nh) { SetSize(w, nh); };
void CopyFrom(FloatImage *source);
};
class VideoFrame {
public:
int w;
int h;
uint32_t size;
unsigned char *data;
VideoFrame();
~VideoFrame();
VideoFrame operator=(VideoFrame rightside);
void SetSize(int nw, int nh);
void SetW(int nw) { SetSize(nw, h); };
void SetH(int nh) { SetSize(w, nh); };
void CopyFrom(VideoFrame *source);
void CopyFrom(FloatImage *source);
};
#endif
Loading…
Cancel
Save