/*
* ImgAnalysisThread.cpp
*
* Created on: Oct 8, 2014
* Author: arturo
*/
#include "ImgAnalysisThread.h"
#include "ofConstants.h"
ImgAnalysisThread::ImgAnalysisThread()
:newFrame(true){
// start the thread as soon as the
// class is created, it won't use any CPU
// until we send a new frame to be analyzed
startThread();
}
ImgAnalysisThread::~ImgAnalysisThread(){
// when the class is destroyed
// close both channels and wait for
// the thread to finish
toAnalyze.close();
analyzed.close();
waitForThread(true);
}
void ImgAnalysisThread::analyze(ofPixels & pixels){
// send the frame to the thread for analyzing
// this makes a copy but we can't avoid it anyway if
// we want to update the grabber while analyzing
// previous frames
toAnalyze.send(pixels);
}
void ImgAnalysisThread::update(){
// check if there's a new analyzed frame and upload
// it to the texture. we use a while loop to drop any
// extra frame in case the main thread is slower than
// the analysis
// tryReceive doesn't reallocate or make any copies
newFrame = false;
while(analyzed.tryReceive(pixels)){
newFrame = true;
}
if(newFrame){
if(!texture.isAllocated()){
texture.allocate(pixels);
}
texture.loadData(pixels);
}
}
bool ImgAnalysisThread::isFrameNew(){
return newFrame;
}
ofPixels & ImgAnalysisThread::getPixels(){
return pixels;
}
ofTexture & ImgAnalysisThread::getTexture(){
return texture;
}
void ImgAnalysisThread::draw(float x, float y){
if(texture.isAllocated()){
texture.draw(x,y);
}else{
ofDrawBitmapString("No frames analyzed yet", x+20, y+20);
}
}
void ImgAnalysisThread::draw(float x, float y, float w, float h){
if(texture.isAllocated()){
texture.draw(x,y,w,h);
}else{
ofDrawBitmapString("No frames analyzed yet", x+20, y+20);
}
}
void ImgAnalysisThread::threadedFunction(){
// wait until there's a new frame
// this blocks the thread, so it doesn't use
// the CPU at all, until a frame arrives.
// also receive doesn't allocate or make any copies
ofPixels pixels;
while(toAnalyze.receive(pixels)){
// we have a new frame, process it, the analysis
// here is just a thresholding for the sake of
// simplicity
pixels.setImageType(OF_IMAGE_GRAYSCALE);
for(auto & p: pixels){
if(p > 80) p = 255;
else p = 0;
}
// once processed send the result back to the
// main thread. in c++11 we can move it to
// avoid a copy
#if __cplusplus>=201103
analyzed.send(std::move(pixels));
#else
analyzed.send(pixels);
#endif
}
}
Comments