package edu.harvard.mcb.leschziner.particlesource;
import java.awt.Rectangle;
import java.util.concurrent.BlockingQueue;
import com.googlecode.javacv.cpp.opencv_core;
import com.googlecode.javacv.cpp.opencv_core.CvMat;
import com.googlecode.javacv.cpp.opencv_core.CvPoint;
import com.googlecode.javacv.cpp.opencv_core.CvRect;
import com.googlecode.javacv.cpp.opencv_imgproc;
import edu.harvard.mcb.leschziner.analyze.BlobExtractor;
import edu.harvard.mcb.leschziner.analyze.CrossCorrelator;
import edu.harvard.mcb.leschziner.core.Particle;
import edu.harvard.mcb.leschziner.storage.DefaultStorageEngine;
import edu.harvard.mcb.leschziner.util.DisplayUtils;
public class TemplatePickingTask extends DistributedPickingTask {
/**
*
*/
private static final long serialVersionUID = 4675358215115778447L;
private final Particle template;
private final double matchThreshold;
private final BlobExtractor blobExtractor;
public TemplatePickingTask(Particle target,
Particle template,
int boxSize,
double matchThreshold,
BlobExtractor extractor,
String particleQueueName,
String executorName) {
super(target, boxSize, particleQueueName, executorName);
this.template = template;
this.matchThreshold = matchThreshold;
this.blobExtractor = extractor;
}
@Override public void process() {
BlockingQueue<Particle> particleQueue = DefaultStorageEngine.getStorageEngine()
.getQueue(particleQueueName);
// Match the template
CvMat matchMat = CrossCorrelator.matchTemplate(target, template);
System.out.println("["
+ this.getClass().getSimpleName()
+ "]: Matched Template");
// Filter out low correlation points
CvMat filteredMat = CvMat.create(matchMat.rows(),
matchMat.cols(),
matchMat.type());
opencv_imgproc.cvThreshold(matchMat,
filteredMat,
matchThreshold,
255,
opencv_imgproc.CV_THRESH_TOZERO);
DisplayUtils.displayMat(filteredMat);
double padding = boxSize / 2.0;
// Find Blobs
Rectangle[] blobs = blobExtractor.extract(filteredMat);
System.out.println("["
+ this.getClass().getSimpleName()
+ "]: "
+ blobs.length
+ " blobs");
for (Rectangle blob : blobs) {
// Pull the match blob
if (blob.x + blob.width < filteredMat.cols()
&& blob.y + blob.height < filteredMat.rows()) {
CvRect cvBlob = BlobExtractor.cvRectFromRectangle(blob);
CvMat regionMat = CvMat.create(cvBlob.width(), cvBlob.height());
opencv_core.cvGetSubRect(filteredMat, regionMat, cvBlob);
// Find Blob Max
CvPoint max = new CvPoint();
opencv_core.cvMinMaxLoc(regionMat,
new double[1],
new double[1],
new CvPoint(),
max,
null);
// Offset that point by the original rect coordinates
int xPick = blob.x + max.x();
int yPick = blob.y + max.y();
// Extract Boxes from original image
// Check that the boxes are fully in bounds
if (xPick + padding < target.getSize()
&& yPick + padding < target.getSize()
&& xPick - padding > 0
&& yPick - padding > 0) {
Particle extracted = target.subParticle((int) (xPick - padding),
(int) (yPick - padding),
boxSize);
// Queue the particle
particleQueue.add(extracted);
}
}
}
}
}