[英]ImageJ - Drawing arrows linking Centroids of Two Images using a Plugin
因此,我正在為我的工作做一個小項目,需要拍攝兩張圖像,一個是核,另一個是高爾基體,並通過箭頭將兩個質心作為端點鏈接起來。 我已經動搖了一段時間,這是我的Java插件源代碼。 顯然有一些錯誤,我對java和imagej都是新手,所以請多多包涵...預先感謝...
因此,我的想法是,一旦將測量結果讀入一個大陣列,我便會繼續尋找每個高爾基體最接近的相應核,然后將它們鏈接起來。 為此,我設置了一個數組並找到了該數組中的最小距離,然后繼續使用在別人的插件中找到的方法進行繪制。
我應該說結果窗口在一堆圖像的兩列中分別顯示x坐標和y坐標,其中一列大約是1000個藍色核和500個紅色高爾基體,最后一列是堆棧中的位置。
我不太確定問題是什么...我不了解如何在圖像處理器上繪制圖像...我一直在閱讀一些教程,但發現它們相對令人困惑...
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import java.util.Arrays;
import java.util.Collections;
import ij.plugin.*;
import ij.plugin.filter.*;
import ij.measure.*;
public class CentroidFinder_ implements PlugInFilter {
protected ImageStack cellstack;
ImagePlus[] cellImages = cellstack.getImageArray();
ImagePlus arrowImage = arrowImage.createImage("ArrayFile", 1600,1200,1);
ResultsTable rt = Analyzer.getResultsTable();
public int setup(String arg, ImagePlus imp) {
cellstack = imp.getStack();
this.imp = imp;
return STACK_REQUIRED;
}
public void run(ImageProcessor ip)
{
int[] blueCentroidsX = {};
int[] blueCentroidsY = {};
int[] redCentroidsX = {};
int[] redCentroidsY = {};
int xColumnIndex = rt.getColumnHeading("X");
int yColumnIndex = rt.getColumnHeading("Y");
int sliceNumberIndex = rt.getColumnHeading("Slice");
float[] sliceCategoryPerRow = (rt.getColumn(sliceNumberIndex));
for (int counter = 0; counter < sliceCategoryPerRow.Length; counter++)
{
if (sliceCategoryPerRow[counter] == 1)
{
blueCentroidsX[counter] = (int)(rt.getValueAsDouble(xColumnIndex, counter)); //This might be a source of error
blueCentroidsY[counter] = (int)(rt.getValue(yColumnIndex, counter));
}
if (sliceCategoryPerRow[counter] == 2)
{
redCentroidsX[counter] = (int)rt.getValue(xColumnIndex, counter); //This might be a source of error
redCentroidsY[counter] = (int)rt.getValue(yColumnIndex, counter);
}
}
if ((blueCentroidsX.length + redCentroidsX.length) =! sliceCategoryPerRow.length)
{
error ("Error Message", "Something is wrong with the columns");
}
boolean blueIsBigger = true;
if (blueCentroidsX.length < redCentroids.length)
blueIsBigger = false;
int[][] startingArrow = {};
int[][] endingArrow = {};
int[][] tempDistance = {};
int counterTag;
float[] distanceList = {};
for (int j = 0; j < redCentroidsX.length; j++)
{
for (int k = 0; k < blueCentroidsX.length; k++)
{
tempDistance = distance (redCentroidsX[j], redCentroidsY[j],
blueCentroidsX[k], blueCentroidsY[k]);
if (throwAwayDistance (tempDistance))
continue;
distanceList = distanceList.addAll({tempDistance, k});
}
if (distanceList.length == 0)
{
break;
}
counterTag = 0;
for (int l = 1; l < distanceList.length; l++)
{
if ((distanceList[l][0] < distanceList[l-1][0]))
counterTag = distanceList[l][1];
}
startingArrow = startingArrow.addAll(({(int)blueCentroidsX[counterTag],
(int)blueCentroidsY[counterTag])});
endingArrow = add(endingArrow, {(int)redCentroidsX[j], int()redCentroidsY[j]});
}
if ((startingArrow.length != endingArrow.length)
error ("Error Message", "Something has caused there not to be equal coordinates");
for (int m = 0; m < startingArrow.length; m++)
{
for (int n = 0; n <endingArrow.length; n++)
{
drawArrow (imp, startingArrow[m][0], startingArrow[m][0],
endingArrow[n][0], endingArrow[n][1], 1)
}
}
stack.addSlice(arrowImage);
public void drawArrow(ImageProcessor ip, int x1, int y1, int x2, int y2, double size)
{
double dx = x2-x1;
double dy = y2-y1;
double ra = java.lang.Math.sqrt(dx*dx + dy*dy);
dx /= ra;
dy /= ra;
int x3 = (int)Math.round(x2-dx*size);
int y3 = (int)Math.round(y2-dy*size);
double r = 0.3*size;
int x4 = (int)Math.round(x3+dy*r);
int y4 = (int)Math.round(y3-dx*r);
int x5 = (int)Math.round(x3-dy*r);
int y5 = (int)Math.round(y3+dx*r);
ip.moveTo(x1, y1); ip.lineTo(x2, y2);
ip.moveTo(x4,y4); ip.lineTo(x2,y2); ip.lineTo(x5,y5);
}
//Mathematical Functions:
public boolean throwAwayDistance (float distance)
{
if (distance >= 25.0)
return true;
else return false;
}
public float distance (x1,y1,x2,y2)
{
int length;
return length = (((x1-x2)^2 + (y1-y2)^2)^(.5));
}
}
Thank you all for all your help!
由於您的代碼無法編譯,因此如果不進行一些調試就很難看到問題所在。
讓我添加一些建議:
既然您說自己對ImageJ和Java都是陌生的,那么您應該在Fiji Wiki上閱讀此介紹 (Fiji是ImageJ的發行版,其中包含許多針對生命科學的有用插件)以及Albert Cardona的出色教程 。
您正在使用旨在處理單個圖像(即ImageProcessor
的PlugInFilter
。 也許使用PlugIn
會更合適,因為您正在使用多個輸入圖像(或通道)並且您的輸出仍在另一個圖像中(盡管它可能在同一堆棧中)
您的drawArrow
方法使用一種低級方法來處理輸出圖像(通過您在需要ImageProcessor
的ImagePlus
上移交它的方式)。 一種更簡單的方法是在記錄命令的同時先在GUI中執行預期的過程,然后在插件中使用以下高級命令:
在Fiji / ImageJ中,單擊Plugins > Macros > Record...
,然后在“記錄:”下拉菜單中選擇Plugin
。
選擇Arrow
工具(在線選擇工具上單擊鼠標右鍵),雙擊以更改設置,在打開的圖像上繪制箭頭,最后通過Image > Overlay > Add Selection...
將其添加到Overlay
。
通過執行以下步驟,您將在Recorder窗口中獲得以下代碼,可以輕松在插件中使用以下代碼,而無需處理任何像素數組:
IJ.run("Arrow Tool...", "width=2 size=10 color=black style=Filled"); imp.setRoi(new Line(92, 184, 189, 131)); IJ.run("Add Selection...", "");
希望能有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.