├── Annotation_to_overlayV1.4.ijm ├── Develop tutorial ├── Code │ ├── Auto Measure and Save.ijm │ ├── AutoBand.ijm │ ├── AutoThreshold to remove scale bar.ijm │ ├── Auto_Measure_Count.ijm │ ├── Create NewImage Dialog.ijm │ ├── Display_Pixel_Values.ijm │ ├── Fill_ROI.ijm │ ├── Manual_Binary.ijm │ ├── Process_subfolders.ijm │ ├── Save all open images.ijm │ ├── String_Process.ijm │ ├── autoConcatenate.ijm │ ├── make_oval_ring.ijm │ └── removeNaN_Inf.ijm ├── ImageJ_Tutorials_NEW_Macro_Writing.pdf ├── README.md ├── imagej_Maco_programming_in_ImageJ.pdf └── macro_reference_guide.pdf ├── IHC_Profiler.zip ├── Measure_Wound_Healing_Coherency.ijm ├── README.md ├── Samples ├── Automatic_counting.tif ├── Mean_Gray_Value.tif └── README.txt ├── _config.yml ├── illumination _correction.ijm ├── newIHC_Profiler.ijm ├── video2img.m ├── zoom_macro_imageJ.ijm └── 专栏图片.png /Annotation_to_overlayV1.4.ijm: -------------------------------------------------------------------------------- 1 | // Macro to add a Rectangular, Oval, Freehand, Straight Line, Arrow or Text selection to an 2 | // overlay. The user can select the slice and frame numbers to add this selection. 3 | 4 | // Kees Straatman, University of Leicester, 12 October 2015 5 | 6 | // version1.2 (Updated 29 May 2017): 7 | // - can handle when there is no selection and does not exit the macro. 8 | // - Instead of asking user in startmenu for first and last frame/slice for their 9 | // selction the user can now move trough the image to set these. 10 | 11 | // Version1.3 (29 May 2018): 12 | // - Resolved a bug causing a flatten error message in single channel time series 13 | // - Improved "Flatten" of stacks 14 | // - Improved the menu so only once the user is asked if the image should 15 | // be "Flattened". 16 | 17 | // Version 1.4 (22 August 2019) 18 | // - Check if an image is open. 19 | // - Resolved a bug in time series 20 | // - Added the option to move the selection after creation after a request from Jayne Squirrell 21 | 22 | macro Annotation_to_overlay{ 23 | t=0; // counter for menu item "Flatten" if it is used more than once 24 | answer = 1; 25 | 26 | // Check for correct image 27 | if (nImages == 0) exit("Image required"); 28 | 29 | while (answer == 1){ 30 | getDimensions(width, height, channels, slices, frames); 31 | if ((slices==1)&&(frames==1)) exit("Sorry, this macro requires a z-stack and/or time series."); 32 | if (isOpen("ROI Manager")) { 33 | selectWindow("ROI Manager"); 34 | run("Close"); 35 | } 36 | 37 | // Create dialog window 38 | Dialog.create("Create overlay"); 39 | 40 | items = newArray("Rectangular", "Oval", "Freehand", "Straight Line", "Arrow", "Text"); 41 | Dialog.addRadioButtonGroup("Selection to add:", items, 2, 3, "Rectangular"); 42 | Dialog.addCheckbox ("Requires to move selection after creation.", false); 43 | if (t==0){ 44 | Dialog.addCheckbox("Flatten image when finished.", false); 45 | } 46 | Dialog.show(); 47 | 48 | // Collect data from dialog window 49 | 50 | selection = Dialog.getRadioButton; 51 | if (selection=="Rectangular") setTool("Rectangular"); 52 | if (selection=="Oval") setTool("Oval"); 53 | if (selection=="Freehand") setTool("Freehand"); 54 | if (selection=="Straight Line") setTool("Straight Line"); 55 | if (selection=="Arrow") setTool("Arrow"); 56 | if (selection=="Text") setTool("Text"); 57 | selectionMove = Dialog.getCheckbox; 58 | if (t==0){ 59 | Fl = Dialog.getCheckbox; 60 | t=1; 61 | } 62 | 63 | 64 | // Draw ROI on overlay 65 | waitForUser("Go to the first slice/frame to start your selection.\nDraw your "+selection+" and click \"OK\""); 66 | if (selectionType()>-1 )roiManager("Add");// Check if there is a selection and add to ROI manager 67 | 68 | Stack.getPosition(channelStart, Zstart, start); 69 | waitForUser("Go to the last slice/frame for this selection and click \"OK\"."); 70 | Stack.getPosition(channelEnd, Zend, end); 71 | 72 | if ((Stack.isHyperstack== true)&&(roiManager("count")>0)){ 73 | for (i=Zstart; i<=Zend;i++){ 74 | for (j=start; j<=end;j++){ 75 | for (c=channelStart; c<=channelEnd; c++){ 76 | roiManager("select",0); 77 | Stack.setPosition(c, i, j); 78 | roiManager("Add"); 79 | } 80 | } 81 | } 82 | // Allow to move selection 83 | if (selectionMove==true){ 84 | for (i=1; i1)&&(roiManager("count")>0)){ 93 | for (i=Zstart; i<=Zend; i++){ 94 | for (c=1; c<=channels; c++){ 95 | roiManager("select",0); 96 | setSlice(i); 97 | run("Add Selection..."); 98 | } 99 | } 100 | // Allow to move selection 101 | if (selectionMove==true){ 102 | run("To ROI Manager"); 103 | for (i=0; i0){ 112 | for (i=start; i<=end; i++){ 113 | roiManager("select",0); 114 | Stack.setDimensions(channels, slices, i); 115 | roiManager("Add"); 116 | } 117 | } 118 | 119 | 120 | // Allow to move selection 121 | if (selectionMove==true){ 122 | 123 | for (i=1; i1) 130 | run("From ROI Manager"); 131 | } 132 | } 133 | 134 | 135 | 136 | if(roiManager("count")>0){ 137 | run("From ROI Manager"); 138 | selectWindow("ROI Manager"); 139 | run("Close"); 140 | } 141 | 142 | 143 | answer = (getBoolean("Do you want to add more anotations?")); 144 | } 145 | if (Fl == true){ 146 | run("Flatten", "stack"); 147 | } 148 | } -------------------------------------------------------------------------------- /Develop tutorial/Code/Auto Measure and Save.ijm: -------------------------------------------------------------------------------- 1 | macro "Auto Measure and Save" 2 | { 3 | dir_saving = getDirectory("Choose a Directory to save"); 4 | dir_processing = getDirectory("Choose a Directory to proess"); 5 | list = getFileList(dir_processing);//Get a List of Images 6 | for(i = 0; i < list.length; i++) 7 | { 8 | open(list[i]);//Open each image 9 | //Measure the Fluorescence 10 | run("8-bit"); 11 | setAutoThreshold("Default dark"); 12 | getThreshold(lower, upper); 13 | setThreshold(lower, upper-1); 14 | run("Measure"); 15 | //Add Fake Color 16 | run("Spectrum"); 17 | saveAs("tiff", dir_saving + getTitle); 18 | close(); 19 | } 20 | } -------------------------------------------------------------------------------- /Develop tutorial/Code/AutoBand.ijm: -------------------------------------------------------------------------------- 1 | // This macro creates multiple donut shaped ROI of pre-defined selection 2 | bandSize = 10; 3 | bandNum = 5; 4 | roiManager("Add"); //Add pre-defined selection 5 | 6 | for (i = 0; i < bandNum; i++) { 7 | roiManager("Select", 0); 8 | run("Make Band...", "band="+bandSize*(i+1)); //Create band 9 | roiManager("Add"); 10 | } 11 | 12 | for (i = 0; i < bandNum-1; i++) { 13 | roiManager("Select", newArray(i+1,i+2)); //Select neighboring bands 14 | roiManager("XOR"); //Create ring 15 | roiManager("Add"); 16 | } 17 | 18 | x = Array.getSequence(bandNum-1); //Create number sequence 19 | 20 | for (i=0; i8bit, 16->16bit, 24->RGB 5 | 6 | if (ImageType != 24){//Not RGB image 7 | ShowValue(xbase, ybase, width, height, "Gray");//Call the ShowValue function 8 | print("This not an RGB image.");} 9 | else {//RGB image 10 | ShowValue(xbase, ybase, width, height, "Red"); 11 | ShowValue(xbase, ybase, width, height, "Green"); 12 | ShowValue(xbase, ybase, width, height, "Blue"); 13 | print("This an RGB image.");} 14 | 15 | function ShowValue(xbase, ybase, width, height, channel) { 16 | for (i = 0; i < width; i++) { 17 | x_position = i + xbase; 18 | for (j = 0; j < height; j++) { 19 | setOption("ShowRowNumbers", false);//Don't show the y axis 20 | setResult("Coordinate",j,j);//Set y coordinate 21 | y_position = j + ybase; 22 | value = getPixel(x_position, y_position); 23 | if (channel == "Gray") { 24 | setResult(i, j, value);} 25 | else if(channel == "Red"){ 26 | setResult(i, j, (value>>16)&0xff);}//(..>>16)&0xff) represents the red channel 27 | else if(channel == "Green"){ 28 | setResult(i, j, (value>>8)&0xff);}//(..>>8)&0xff) represents the green channel 29 | else if(channel == "Blue"){ 30 | setResult(i, j, value&0xff);}//(..&0xff) represents the blue channel 31 | } 32 | } 33 | Table.rename("Results", channel);//Important for separate different results 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Develop tutorial/Code/Fill_ROI.ijm: -------------------------------------------------------------------------------- 1 | //This macro fills ROI with certain color by its pixel value. 2 | macro "fill_ROI" { 3 | run("Select None");//Remove all the selections 4 | roiManager("reset");//Reset the ROI manager 5 | 6 | image_roi = getTitle(); 7 | run("Duplicate...", "duplicate"); //Duplicate the image stack 8 | image_fill = getTitle(); 9 | run("RGB Color"); 10 | 11 | fill_ROI(1,"1","#d05151"); //Call the self-defined function 12 | fill_ROI(2,"2","#26a526"); //You should input three parameters: 13 | fill_ROI(3,"3","#a6a627"); //Pixel value, ROI_Label_name and Color Code 14 | 15 | function fill_ROI(value,label,color) { 16 | //Get the ROI by its gray value 17 | for (i = 1; i < nSlices+1; i++) { //Loop to traverse all slices 18 | selectWindow(image_roi); 19 | setSlice(i); // 20 | setThreshold(value, value); //Threshold to select certain pixel value 21 | run("Create Selection"); 22 | if (selectionType() ==-1) { //If there is on selection 23 | print("There is no " + label +" in " + i +" slice."); 24 | } 25 | else { 26 | roi_name = label+"_"+i; 27 | Roi.setName(roi_name); 28 | roiManager("Add"); 29 | roiManager("Measure"); 30 | } 31 | } 32 | //Fill ROI with certain color 33 | n = roiManager("count"); 34 | for (j = 0; j < n; j++) { //Loop to traverse all ROI 35 | selectWindow(image_fill); 36 | roiManager("select", j); 37 | setColor(color); 38 | fill(); 39 | } 40 | run("Select None"); //Remove all the selections 41 | roiManager("reset"); //Reset the ROI manager 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Develop tutorial/Code/Manual_Binary.ijm: -------------------------------------------------------------------------------- 1 | macro "Manual_Binary" { 2 | width = getWidth(); 3 | height = getHeight(); 4 | upper_threshold = 100; 5 | lower_threshold = 30; 6 | run("8-bit");//Set pixel value to 0~255 7 | 8 | for (i = 0; i < width; i++) { 9 | for (j = 0; j < height; j++) 10 | { 11 | pixel_value = getPixel(i, j); //Get every pixel value 12 | if (pixel_value > lower_threshold && pixel_value < upper_threshold) { 13 | setPixel(i, j, 255);} 14 | else { 15 | setPixel(i, j, 0);} 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Develop tutorial/Code/Process_subfolders.ijm: -------------------------------------------------------------------------------- 1 | // This macro processes all the images in a folder and any subfolders. 2 | macro "Process_subfolders" { 3 | path = getDirectory("Choose Source Directory "); 4 | setBatchMode(true);//Prevent images from showing up to speed up 5 | process_all(path); 6 | 7 | function process_all(path) {//Recursion function 8 | list = getFileList(path); 9 | for (i=0; i1000) { 11 | setPixel(i, j, 0); 12 | } 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Develop tutorial/ImageJ_Tutorials_NEW_Macro_Writing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanzhao9/ImageJ-Tutorial/4eb47ca01e4a8af8aa14491a8d4e7625a15a6a9e/Develop tutorial/ImageJ_Tutorials_NEW_Macro_Writing.pdf -------------------------------------------------------------------------------- /Develop tutorial/README.md: -------------------------------------------------------------------------------- 1 | #### This folder contains all the macro codes(The [Code folder](https://github.com/inanezhao/ImageJ-Tutorial/tree/master/Develop%20tutorial/Code)) and some useful textbook. 2 | 3 | #### For batch downloading, you can download the [GitZip](https://chrome.google.com/webstore/detail/gitzip-for-github/ffabmkklhbepgcgfonabamgnfafbdlkn) 4 | 5 | #### Hope you enjoy! 6 | -------------------------------------------------------------------------------- /Develop tutorial/imagej_Maco_programming_in_ImageJ.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanzhao9/ImageJ-Tutorial/4eb47ca01e4a8af8aa14491a8d4e7625a15a6a9e/Develop tutorial/imagej_Maco_programming_in_ImageJ.pdf -------------------------------------------------------------------------------- /Develop tutorial/macro_reference_guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanzhao9/ImageJ-Tutorial/4eb47ca01e4a8af8aa14491a8d4e7625a15a6a9e/Develop tutorial/macro_reference_guide.pdf -------------------------------------------------------------------------------- /IHC_Profiler.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanzhao9/ImageJ-Tutorial/4eb47ca01e4a8af8aa14491a8d4e7625a15a6a9e/IHC_Profiler.zip -------------------------------------------------------------------------------- /Measure_Wound_Healing_Coherency.ijm: -------------------------------------------------------------------------------- 1 | /** 2 | * Measure Wound Healing using Coherency 3 | * Collaborators: 4 | * Kelsey Quinn 5 | * 6 | * Measure the area of a wound in a cellular tissue on a stack 7 | * of images representing a time-series. The macro needs FeatureJ and 8 | * MorphoLibJ to be installed. 9 | * The coherency function has been written by Arnold Fertin. 10 | * 11 | * (c) 2016, INSERM 12 | * written by Volker Baecker at Montpellier RIO Imaging (www.mri.cnrs.fr) 13 | * 14 | */ 15 | 16 | var _CLOSE_RADIUS = 20; 17 | var _OPEN_RADIUS = 20; 18 | var _CLOSE_BIG_RADIUS = 80; 19 | var _MIN_SIZE = 20000; 20 | var _COHERENCY_SIGMA = 0.250; 21 | var _COHERENCY_WINDOW_SIZE = 5; 22 | 23 | var helpURL = "http://dev.mri.cnrs.fr/wiki/imagej-macros/Wound_Healing_Coherency_Tool" 24 | 25 | macro "MRI Wound Healing Coherency Help Action Tool - CaaaD03D0fD1eD21D2eD2fD30D3eD46D53D54D58D63D64D66D72D74D76D85D86D87D93D97D9bD9fDa9DaaDabDafDbbDbcDbdDbfC999D02D09D0dD18D1cD28D2dD36D7eD8fDccDcfDd4DdbDdfDfeDffCbbbD20D51D62D84Da5Da8Db1Db9DcbDd5De1De8Df0C777D14D15D16D5dD6cDdcDe2De3CbbbD04D05D10D1aD3fD43D44D4fD52D56D5fD61D67D7cD8aD8bD98D9cD9dD9eDacDadDaeDbaDbeDd9CaaaD00D06D0aD0bD11D1bD1dD1fD2bD31D32D33D34D37D38D39D3aD3bD4eD55D65D75D77D78D88D89D8cD99D9aDb3Db8Dc4Df7CcccD29D2aD69D7aD83D96Db4C666D48D49D4aD4bD4cD59D5cD6aD82Da1Da7Dc0Dd7DddDdeDeaDebDecDedDeeDf5Df6Df9DfaDfbC999D0cD0eD22D23D35D42D45D60D6fD7dD8eDa3Db2DceDf4Df8CcccD19D47D57D68D73D79D7bDdaDe0C888D01D07D08D12D13D24D25D26D2cD3cD3dD41D4dD50D5eD6eD7fD8dDc5Dc8DcdDd6Dd8De4De5DefDfdCdddD95Da0Da4Db0Dc9DcaDe7Df2Df3C444D5aD5bD70D71D80D90Da2Da6Db5Dc6Dd3De9C888D17D27D40D6dDd0De6DfcCdddD94Df1"{ 26 | run('URL...', 'url='+helpURL); 27 | } 28 | 29 | macro 'Measure Wound Healing Coherency Action Tool - C000T4b12m' { 30 | measureTimeSeries(); 31 | } 32 | 33 | macro 'Measure Wound Healing Coherency Action Tool Options' { 34 | Dialog.create("Wound Healing Coherency Options"); 35 | Dialog.addNumber("radius close", _CLOSE_RADIUS); 36 | Dialog.addNumber("radius open", _OPEN_RADIUS); 37 | Dialog.addNumber("radius big close", _CLOSE_BIG_RADIUS); 38 | Dialog.addNumber("min. size", _MIN_SIZE); 39 | Dialog.addNumber("sigma for coherency", _COHERENCY_SIGMA); 40 | Dialog.addNumber("window size for coherency", _COHERENCY_WINDOW_SIZE); 41 | Dialog.show(); 42 | _CLOSE_RADIUS = Dialog.getNumber(); 43 | _OPEN_RADIUS = Dialog.getNumber(); 44 | _CLOSE_BIG_RADIUS = Dialog.getNumber(); 45 | _MIN_SIZE = Dialog.getNumber(); 46 | _COHERENCY_SIGMA = Dialog.getNumber(); 47 | _COHERENCY_WINDOW_SIZE = Dialog.getNumber(); 48 | } 49 | 50 | function measureTimeSeries() { 51 | roiManager("Reset"); 52 | roiManager("Associate", "true"); 53 | for(i=1; i<=nSlices; i++) { 54 | setSlice(i); 55 | run("Select None"); 56 | run("Duplicate...", "use"); 57 | measureTissueArea(); 58 | close(); 59 | run("Restore Selection"); 60 | roiManager("Add"); 61 | } 62 | setSlice(1); 63 | run("Select None"); 64 | roiManager("Show All"); 65 | } 66 | 67 | function measureTissueArea() { 68 | coherency(); 69 | run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); 70 | selectWindow("Coherency"); 71 | setAutoThreshold("Triangle dark"); 72 | setOption("BlackBackground", false); 73 | run("Convert to Mask"); 74 | run("Morphological Filters", "operation=Closing element=Square radius=" + _CLOSE_RADIUS); 75 | run("Morphological Filters", "operation=Opening element=Square radius=" + _OPEN_RADIUS); 76 | run("Analyze Particles...", "size="+_MIN_SIZE+"-Infinity show=Masks"); 77 | run("Morphological Filters", "operation=Closing element=Disk radius=" + _CLOSE_BIG_RADIUS); 78 | run("Create Selection"); 79 | close(); 80 | close(); 81 | close(); 82 | close(); 83 | close(); 84 | run("Restore Selection"); 85 | run("Make Inverse"); 86 | run("Measure"); 87 | } 88 | 89 | function coherency() { 90 | sigma = _COHERENCY_SIGMA; 91 | windowSize = _COHERENCY_WINDOW_SIZE; 92 | 93 | setBatchMode(true); 94 | 95 | run("FeatureJ Structure", "largest smallest smoothing=" + sigma + " integration=" + windowSize); 96 | 97 | list = getList("image.titles"); 98 | for (i=0; i 10 | 11 | [ImageJ实用教程](https://zhuanlan.zhihu.com/c_1069243926476673024) 12 | 13 | [ImageJ开发教程](https://zhuanlan.zhihu.com/c_1101076075773370368) 14 | 15 | This repository contains: 16 | 1. Macro codes(Located in [Develop tutorial](https://github.com/inanezhao/ImageJ-Tutorial/tree/master/Develop%20tutorial) folder) 17 | 2. Textbooks 18 | 3. Plugins files 19 | 4. Sample images 20 | 21 | **Any questions, please contact me via email**: zhaoyc9@163.com 22 | 23 | Hope you enjoy! 24 | 25 | Ethan Zhao 26 | 27 | -------------------------------------------------------------------------------- /Samples/Automatic_counting.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanzhao9/ImageJ-Tutorial/4eb47ca01e4a8af8aa14491a8d4e7625a15a6a9e/Samples/Automatic_counting.tif -------------------------------------------------------------------------------- /Samples/Mean_Gray_Value.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanzhao9/ImageJ-Tutorial/4eb47ca01e4a8af8aa14491a8d4e7625a15a6a9e/Samples/Mean_Gray_Value.tif -------------------------------------------------------------------------------- /Samples/README.txt: -------------------------------------------------------------------------------- 1 | This folder contains all the sample images of ImageJ tutorial. 2 | Feel free to download and practice. 3 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /illumination _correction.ijm: -------------------------------------------------------------------------------- 1 | //This macro is used for z-axis illumination correction. 2 | macro "Illumination_Correction" { 3 | run("16-bit");//Avoid overexposure 4 | for (i = 0; i < nSlices; i++) { 5 | selectWindow("Plot Values"); 6 | first_value = Table.get("Y0",0);//Select first slice for normalization 7 | slice_value = Table.get("Y0",i); 8 | correction_ind = slice_value/first_value; 9 | setSlice(i+1);//Next slice 10 | run("Divide...", "value=" + correction_ind + " slice");//Divide by correction index 11 | print(i+1); 12 | } 13 | run("8-bit"); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /newIHC_Profiler.ijm: -------------------------------------------------------------------------------- 1 | // This macro has been developed to calculate the number of pixels of 2 | // different color intensities and based on that it plots a histogram 3 | // profile and assigns a grade to the image. 4 | // Modiied by Ethan Zhao 5 | // First, do Color Deconvolution to seperate the channel to be analyzed 6 | // Then, run this macro to get the results 7 | 8 | title = getTitle(); 9 | print(title); 10 | 11 | Region2=0; 12 | Region3=0; 13 | Region4=0; 14 | Region1=0; 15 | Region0=0; 16 | TotalPixel=0; 17 | PercentRegion1=0; 18 | PercentRegion2=0; 19 | PercentRegion4=0; 20 | PercentRegion3=0; 21 | PercentRegion0=0; 22 | bins = 256; 23 | maxCount = 0; 24 | histMin = 0; 25 | histMax = 0; 26 | 27 | if (histMax>0) 28 | getHistogram(values, counts, bins, histMin, histMax); 29 | else 30 | getHistogram(values, counts, bins); 31 | 32 | min = 9999999; 33 | max = -9999999; 34 | 35 | for (i=0; i0) 39 | { 40 | n += count; 41 | sum += count*i; 42 | if (imax) max = i; 44 | } 45 | } 46 | 47 | 48 | for (i=0; i=0 && i<61) 51 | Region4=Region4+counts[i]; 52 | if (i>60 && i<121) 53 | Region3=Region3+counts[i]; 54 | if (i>120 && i<181) 55 | Region2=Region2+counts[i]; 56 | if (i>180 && i<236) 57 | Region1=Region1+counts[i]; 58 | if (i>235 && i<=256) 59 | Region0=Region0+counts[i]; 60 | } 61 | 62 | TotalPixel=TotalPixel+Region1+Region2+Region3+Region4+Region0; 63 | 64 | PixelUnderConsideration=TotalPixel-Region0; 65 | 66 | PercentRegion3=(Region3/PixelUnderConsideration)*100; 67 | 68 | PercentRegion2=(Region2/PixelUnderConsideration)*100; 69 | 70 | PercentRegion1=(Region1/PixelUnderConsideration)*100; 71 | 72 | PercentRegion4=(Region4/PixelUnderConsideration)*100; 73 | 74 | print("Percentage contibution of High Positive: "+PercentRegion4); 75 | 76 | print("Percentage contibution of Positive: "+PercentRegion3); 77 | 78 | print("Percentage contibution of Low Positive: "+PercentRegion2); 79 | 80 | print("Percentage contibution of Negative: "+PercentRegion1); 81 | 82 | -------------------------------------------------------------------------------- /video2img.m: -------------------------------------------------------------------------------- 1 | %% This script can convert video into series of images 2 | clc;clear; 3 | obj = VideoReader('test.avi'); 4 | vid = read(obj); 5 | frames = obj.NumberOfFrames; 6 | for ii = 1 : frames 7 | % imwrite(vid(:,:,:,x),strcat('frame-',num2str(x),'.png')); 8 | imwrite(vid(:,:,:,ii),['output\',num2str(ii),'.tif']); 9 | end -------------------------------------------------------------------------------- /zoom_macro_imageJ.ijm: -------------------------------------------------------------------------------- 1 | /* 2 | ImageJ macro making a movie (stack) of zooming on selected rectangle (ROI) 3 | v2 Eugene Katrukha katpyxa at gmail.com 4 | v2a Andrey Aristov: aaristov at pasteur.fr 5 | v2b Lachlan Whitehead: whitehead at wehi.edu.au 6 | distortion when scaling bug fix by Jürgen Gluch: juergen.gluch at gmail.com 7 | */ 8 | requires("1.48h"); 9 | 10 | function main(){ 11 | print("\\Clear"); 12 | if(nImages==0){ 13 | exit("No image open"); 14 | } 15 | 16 | sTitle = getTitle(); 17 | sMovieTitle=sTitle+"_zoom_movie"; 18 | rawID=getImageID(); 19 | getDimensions(imageW,imageH,c,z,totalFrames); 20 | if(totalFrames > 1){ 21 | isTimeLapse = true; 22 | }else{ 23 | isTimeLapse = false; 24 | } 25 | 26 | if(selectionType() == -1){ 27 | exit("No roi selected"); 28 | } 29 | Stack.getPosition(dummy, dummy, targetFrame) 30 | Roi.getBounds(nX, nY, nW, nH); 31 | 32 | //fix Aspect ratio of roi 33 | nH = nW * imageH / imageW; 34 | makeRectangle(nX, nY, nW, nH); 35 | 36 | 37 | ratio = nW / imageW; 38 | 39 | //Display options 40 | OptionsMenu(); 41 | 42 | nFinalH = nFinalW *(imageH/imageW); 43 | 44 | 45 | setBatchMode(true); 46 | print("Processing Zoom Movie"); 47 | 48 | zoomStep = exp(log(ratio)/finalLength); //calculate zoom step from menu option 49 | 50 | nCenterX=nX+0.5*nW; 51 | nCenterY=nY+0.5*nH; 52 | nScaleX=nW / imageW; 53 | nScaleY=nH / imageH; 54 | 55 | 56 | //adjust roi x/y ratio to image x/y ratio 57 | //depending on user choice - not sure this is entirely necessary 58 | if(startsWith(sChoice, "min")){ 59 | nScaleFin=minOf(nScaleX,nScaleY); 60 | }else{ 61 | nScaleFin=maxOf(nScaleX,nScaleY); 62 | } 63 | 64 | nW=nScaleFin*imageW; 65 | nH=nScaleFin*imageH; 66 | nX=nCenterX-(nW*0.5); 67 | nY=nCenterY-(nH*0.5); 68 | 69 | 70 | //distance from (0,0) to left top corner of selection 71 | length=sqrt(nX*nX+nY*nY); 72 | if(nX==0){ 73 | angle=3.14/2; 74 | }else{ 75 | angle=atan(nY/nX); 76 | } 77 | 78 | if(startsWith(sSizeChoice,"same as")){ 79 | nFinalW=nW; 80 | nFinalH=nH; 81 | 82 | }else{ 83 | 84 | nMovieScaleX=nW/nFinalW; 85 | nMovieScaleY=nH/nFinalH; 86 | nFinalW=nW / nMovieScaleX; 87 | nFinalH=nH / nMovieScaleY; 88 | 89 | } 90 | 91 | 92 | bNotFirstIt=false; 93 | 94 | dCount =0; 95 | nScale=1; 96 | 97 | newW=imageW; 98 | newH=imageH; 99 | dLen = length; 100 | ddLen = 0; 101 | 102 | run("Set Scale...", "distance=1 known="+px+" pixel=1 unit=um"); 103 | print("\\Update1:Calculating zoom"); 104 | 105 | //process zooming step 106 | currentFrame = startZoomAtFrame; 107 | while(newW>nW){ 108 | selectImage(rawID); 109 | if(isTimeLapse){ 110 | Stack.setFrame(currentFrame); 111 | } 112 | offsetX=ddLen*cos(angle); 113 | offsetY=ddLen*sin(angle); 114 | 115 | // if selction goes outside the image, we have to shift the selection 116 | // otherwise the ducplicate is a cropped version and gets distorded 117 | // bugfix by Jurgen Gluch 118 | if (newW+offsetX > imageW) {offsetX = imageW-newW;} 119 | if (newH+offsetY > imageH) {offsetY = imageH-newH;} 120 | 121 | run("Specify...", "width="+toString(newW)+" height="+toString(newH)+" x="+toString(offsetX)+" y="+toString(offsetY)); 122 | 123 | makeNextFrame(); 124 | 125 | if(addScaleBar){ 126 | putScaleBarOn(); 127 | } 128 | 129 | if(bNotFirstIt){ 130 | sCurrTitle=sTitle+"x"+toString(nScale); 131 | rename(sCurrTitle); 132 | run("Concatenate...", " title=["+sMovieTitle+"] image1=["+sMovieTitle+"] image2=["+sCurrTitle+"]"); 133 | }else{ 134 | rename(sMovieTitle); 135 | sMovieID=getImageID(); 136 | bNotFirstIt=true; 137 | } 138 | 139 | //updateZoom 140 | dLen=dLen*zoomStep; 141 | ddLen = length-dLen+length*nScaleFin; 142 | 143 | newW=newW*zoomStep; 144 | newH=newH*zoomStep; 145 | if(playWhileZooming){ 146 | currentFrame++; 147 | } 148 | 149 | } 150 | lastFrame = currentFrame; 151 | 152 | if(isTimeLapse && startZoomAtFrame != 1){ 153 | print("\\Update1:Appending initial frames"); 154 | selectImage(rawID); 155 | run("Select None"); 156 | Stack.getDimensions(x, x, nChannels, x, x); 157 | if(nChannels>1){ 158 | run("Duplicate...","title=prologue duplicate frames=1-"+startZoomAtFrame-1); 159 | }else{ 160 | run("Duplicate...","title=prologue duplicate range=1-"+startZoomAtFrame-1); 161 | } 162 | 163 | run("Scale...", "x=- y=- width="+toString(nFinalW)+" height="+toString(nFinalH)+" interpolation=Bicubic process average create"); 164 | 165 | close("prologue"); 166 | if(addScaleBar){ 167 | putScaleBarOn(); 168 | } 169 | 170 | run("Concatenate...", " title=["+sMovieTitle+"] image1=[prologue-1] image2=["+sMovieTitle+"]"); 171 | } 172 | 173 | 174 | //if it's a time lapse and append remaining frames has been selected, do that 175 | if(isTimeLapse && appendEpilogue){ 176 | if(lastFrame0){ 209 | print("\\Update1:Appending static tiles"); 210 | selectImage(sMovieTitle); 211 | Stack.getDimensions(blah, blah, blah, blah, nFrames); 212 | for(n=1;n<=nFramesLast;n++){ 213 | Stack.setFrame(nFrames); 214 | Stack.setSlice(nSlices()); 215 | run("Duplicate...","title=staticFrame"); 216 | run("Concatenate...", " title=["+sMovieTitle+"] image1=["+sMovieTitle+"] image2=[staticFrame]"); 217 | } 218 | } 219 | setBatchMode(false); 220 | print("\\Clear"); 221 | print("Done!"); 222 | } 223 | 224 | 225 | 226 | 227 | 228 | function OptionsMenu(){ 229 | 230 | 231 | Dialog.create("Zoom-in parameters:"); 232 | //Dialog.addNumber("Zoom Step (0 to 1)",0.95); 233 | if(isTimeLapse){ 234 | Dialog.addNumber("How many frames to spend zooming in? (approx)",targetFrame); 235 | Dialog.setInsets(0, 93, 0) 236 | Dialog.addCheckbox("Append the remaining frames post-zoom?",true); 237 | Dialog.addNumber("Start zoom on frame",1); 238 | Dialog.setInsets(0, 150, 15) 239 | Dialog.addCheckbox("Continue playing during zoom",true); 240 | }else{ 241 | Dialog.addNumber("How many frames to spend zooming in? (approx)",35); 242 | } 243 | Dialog.addNumber("Add static number of frames in the end:", 5); 244 | minMax=newArray("min","max"); 245 | Dialog.addChoice("_Zoom to min/max ROI size:", minMax); 246 | sScaleChoice=newArray("Specified below","same as ROI"); 247 | Dialog.addChoice("Final movie dimensions (px):", sScaleChoice); 248 | Dialog.addNumber("_Final movie width:", 512); 249 | Dialog.setInsets(10, 170, 0) 250 | Dialog.addCheckbox("_Add scalebar:", false); 251 | Dialog.addNumber("Pixel size, um:", 0.04); 252 | 253 | Dialog.show(); 254 | 255 | //zoomStep=Dialog.getNumber(); 256 | if(isTimeLapse){ 257 | finalLength = Dialog.getNumber(); 258 | appendEpilogue = Dialog.getCheckbox(); 259 | startZoomAtFrame = Dialog.getNumber(); 260 | playWhileZooming = Dialog.getCheckbox(); 261 | 262 | }else{ 263 | finalLength = Dialog.getNumber(); 264 | } 265 | 266 | nFramesLast=Dialog.getNumber(); 267 | sChoice=Dialog.getChoice(); 268 | sSizeChoice=Dialog.getChoice(); 269 | nFinalW=Dialog.getNumber(); 270 | addScaleBar = Dialog.getCheckbox(); 271 | px=Dialog.getNumber(); 272 | } 273 | 274 | function makeNextFrame(){ 275 | run("Duplicate...", "title="+sTitle+toString(nScale)); 276 | unscaledID=getImageID(); 277 | run("Scale...", "x=- y=- width="+toString(nFinalW)+" height="+toString(nFinalH)+" interpolation=Bicubic average create"); 278 | scaledID=getImageID(); 279 | selectImage(unscaledID); 280 | close(); 281 | selectImage(scaledID); 282 | //run("Enhance Contrast...", "saturated=0.3"); 283 | } 284 | 285 | function putScaleBarOn(){ 286 | 287 | trueSize = newW*px;//um 288 | 289 | w = floor(trueSize/2); 290 | if(w>300){ 291 | width = 300; 292 | } 293 | else if(w>100){ 294 | width = 100; 295 | } 296 | else if(w>30){ 297 | width = 30; 298 | } 299 | else if(w>10){ 300 | width = 10; 301 | } 302 | else if(w>3){ 303 | width = 3; 304 | } 305 | else { 306 | width = 1; 307 | } 308 | 309 | 310 | run("Scale Bar...", "width="+width+" height=8 font=24 color=White background=None location=[Lower Right] bold label"); 311 | 312 | } 313 | 314 | //Global variables - mostly for menu 315 | var zoomStep=1; 316 | var nFramesLast=1; 317 | var sChoice=1; 318 | var sSizeChoice=1; 319 | var nFinalW=1; 320 | var nFinalH=1; 321 | var addScaleBar = 1; 322 | var px=1; 323 | var finalLength=1; 324 | var appendEpilogue = true; 325 | var isTimeLapse = false; 326 | var currentFrame=1; 327 | var startZoomAtFrame = 1; 328 | var playWhileZooming = true; 329 | 330 | main(); -------------------------------------------------------------------------------- /专栏图片.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanzhao9/ImageJ-Tutorial/4eb47ca01e4a8af8aa14491a8d4e7625a15a6a9e/专栏图片.png --------------------------------------------------------------------------------