package resa.evaluation.topology.tomVLD;
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static resa.evaluation.topology.tomVLD.Constants.*;
/**
* Created by Tom Fu at Mar 24, 2015
* This bolt is designed to collect the found rects from the Patch Process bolt,
* When all the found rect message (the found rect data can be null) is received (#messages == patch_count)
* It sends out the foundRectList to the patchDraw bolt
* IN ResaVLDTopFoxBC, the sampling bug is fiexed.
*/
public class PatchAggBoltMultipleBeta extends BaseRichBolt {
OutputCollector collector;
/* Keeps track on which patches of the certain frame have already been received */
//Map< Integer, HashSet<Serializable.Rect> > frameAccount;
Map< Integer, Integer> frameMonitor;
/* Contains the list of logos found found on a given frame */
Map< Integer, List<List<Serializable.Rect>> > foundRectAccount;
private int sampleFrames;
@Override
public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) {
this.collector = outputCollector;
frameMonitor = new HashMap<>();
foundRectAccount = new HashMap<>();
sampleFrames = ConfigUtil.getInt(map, "sampleFrames", 1);
}
//Fields("frameId", "framePatchIdentifier", "foundRect", "patchCount"));
@Override
public void execute(Tuple tuple) {
//opencv_core.IplImage fk = new opencv_core.IplImage();
int frameId = tuple.getIntegerByField(FIELD_FRAME_ID);
int patchCount = tuple.getIntegerByField(FIELD_PATCH_COUNT);
List<Serializable.Rect> foundRect = (List<Serializable.Rect>)tuple.getValueByField(FIELD_FOUND_RECT);
if (!foundRectAccount.containsKey(frameId)){
foundRectAccount.put(frameId, new ArrayList<>());
for (int logoIndex = 0; logoIndex < foundRect.size(); logoIndex ++) {
foundRectAccount.get(frameId).add(new ArrayList<>());
}
}
/* Updating the list of detected logos on the frame */
for (int logoIndex = 0; logoIndex < foundRect.size(); logoIndex ++) {
if (foundRect.get(logoIndex) != null) {
foundRectAccount.get(frameId).get(logoIndex).add(foundRect.get(logoIndex));
}
}
frameMonitor.computeIfAbsent(frameId, k->0);
frameMonitor.computeIfPresent(frameId, (k,v)->v+1);;
/* If all patches of this frame are collected proceed to the frame aggregator */
if (frameMonitor.get(frameId) == patchCount) {
if (frameId % sampleFrames == 0) {
for (int f = frameId; f < frameId + sampleFrames; f ++){
collector.emit(PROCESSED_FRAME_STREAM, new Values(f, foundRectAccount.get(frameId)));
//System.out.println("processed frame stream, frameID: " + f);
}
}
frameMonitor.remove(frameId);
foundRectAccount.remove(frameId);
collector.emit(CACHE_CLEAR_STREAM, tuple, new Values(frameId));
}
collector.ack(tuple);
}
@Override
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
outputFieldsDeclarer.declareStream(PROCESSED_FRAME_STREAM, new Fields(FIELD_FRAME_ID, FIELD_FOUND_RECT_LIST));
outputFieldsDeclarer.declareStream(CACHE_CLEAR_STREAM, new Fields(FIELD_FRAME_ID));
}
}