Skip to content

Commit

Permalink
Fix #210 and #164
Browse files Browse the repository at this point in the history
  • Loading branch information
NicoKiaru committed Aug 30, 2024
1 parent 8816adc commit 0cabef8
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import ch.epfl.biop.sourceandconverter.processor.SourcesProcessor;
import ch.epfl.biop.sourceandconverter.processor.SourcesProcessorHelper;
import com.google.gson.Gson;
import ij.IJ;
import ij.ImagePlus;
import ij.process.ColorProcessor;
import net.imglib2.realtransform.AffineTransform3D;
import org.scijava.Context;
import org.scijava.InstantiableException;
Expand Down Expand Up @@ -124,6 +127,18 @@ public void run() {
return;
}

if (!channels.trim().equals("*")) {
List<Integer> indices = Arrays.stream(channels.trim().split(",")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());

int maxIndex = indices.stream().mapToInt(e -> e).max().getAsInt();

if (maxIndex>=mp.getChannelBoundForSelectedSlices()) {
mp.errorMessageForUser.accept("Missing channel in selected slice(s).",
"Missing channel in selected slice(s)\n One selected slice only has "+mp.getChannelBoundForSelectedSlices()+" channel(s).\n Maximum index : "+(mp.getChannelBoundForSelectedSlices()-1) );
return;
}
}

setPixelSizeFromModel();

TempDirectory td = new TempDirectory("deepslice");
Expand Down Expand Up @@ -423,21 +438,12 @@ protected void exportDownsampledDataset(List<SliceSources> slices) {

if (!channels.trim().equals("*")) {
List<Integer> indices = Arrays.stream(channels.trim().split(",")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());

int maxIndex = indices.stream().mapToInt(e -> e).max().getAsInt();

if (maxIndex>=mp.getChannelBoundForSelectedSlices()) {
mp.errorMessageForUser.accept("Missing channel in selected slice(s).",
"Missing channel in selected slice(s)\n One selected slice only has "+mp.getChannelBoundForSelectedSlices()+" channel(s).\n Maximum index : "+(mp.getChannelBoundForSelectedSlices()-1) );
return;
}

preprocess = new SourcesChannelsSelect(indices);
}

try {

QuickNIIExporter.builder()
List<String> filePaths = QuickNIIExporter.builder()
.roi(mp.getROI())
.cvt8bits(convert_to_8_bits)
.jpeg(convert_to_jpg)
Expand All @@ -450,6 +456,27 @@ protected void exportDownsampledDataset(List<SliceSources> slices) {
.create()
.export();

double ratioSaturatedPixelValueThreshold = 0.02; // Should not have saturated pixel in more than 5% of the pixel
String message = "";
int iSaturatedCounter = 0;
for (int i = 0; i< filePaths.size(); i++) {
double saturationForImage = calculateSaturatedPixelRatio(IJ.openImage(filePaths.get(i)));
if (saturationForImage > ratioSaturatedPixelValueThreshold) {
message += slices.get(i).getName()+" is saturated above "+((int)(ratioSaturatedPixelValueThreshold*100))+" % ("+((int)(saturationForImage*100))+" %) \n";
iSaturatedCounter++;
}
if (iSaturatedCounter>20) {
message += "...";
break;
}
}

if (!message.isEmpty()) {
mp.warningMessageForUser.accept("Slices saturated!", "DeepSlice will run but results won't be optimal. Please change display settings to avoid saturation: \n"+message);
} else {

}

} catch (Exception e) {
mp.errorMessageForUser.accept("Export to Quick NII dataset error. ", e.getMessage());
}
Expand All @@ -463,4 +490,31 @@ private void setPixelSizeFromModel() {
}
}

// See https://github.com/BIOP/ijp-imagetoatlas/issues/164
public static double calculateSaturatedPixelRatio(ImagePlus image) {
if (!(image.getProcessor() instanceof ColorProcessor)) {
return 0;
}
ColorProcessor processor = (ColorProcessor) image.getProcessor();
int width = processor.getWidth();
int height = processor.getHeight();
int saturatedPixelCount = 0;

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = processor.getPixel(x, y);
int red = (pixel >> 16) & 0xFF;
int green = (pixel >> 8) & 0xFF;
int blue = pixel & 0xFF;

if (red == 255 || green == 255 || blue == 255) {
saturatedPixelCount++;
}
}
}

double totalPixels = width * height;
return (double) saturatedPixelCount / totalPixels;
}

}
58 changes: 18 additions & 40 deletions src/main/java/ch/epfl/biop/quicknii/QuickNIIExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ public static Builder builder() {
return new Builder();
}

public void export() throws Exception {
public List<String> export() throws Exception {

List<String> filePaths = new ArrayList<>();

// Creates
if (!datasetFolder.exists()) {
Expand All @@ -63,11 +65,10 @@ public void export() throws Exception {
}
}

if (slices.size()==0) {
return;
if (slices.isEmpty()) {
return filePaths;
}


DecimalFormat df = new DecimalFormat("000");
IntStream.range(0,slices.size()).parallel().forEach(i -> {
SliceSources slice = slices.get(i);
Expand All @@ -88,54 +89,31 @@ public void export() throws Exception {
if (ratioSaturated > 0.15) {
IJ.log("Image "+imp.getTitle()+" is oversaturated! (>15%), please adjust B&C of the channel before export!! ");
}*/
IJ.saveAs(imp,"jpeg",
datasetFolder.getAbsolutePath() + File.separator + // Folder
imageName + "_s" + df.format(i) + ".jpg" // image name, three digits, and underscore s

String filePath = datasetFolder.getAbsolutePath() + File.separator + // Folder
imageName + "_s" + df.format(i) + ".jpg";
IJ.saveAs(imp,"jpeg", filePath
// image name, three digits, and underscore s
);
filePaths.add(filePath);

} else {
IJ.save(imp,
datasetFolder.getAbsolutePath() + File.separator + // Folder
imageName + "_s" + df.format(i) + ".tif" // image name, three digits, and underscore s
String filePath = datasetFolder.getAbsolutePath() + File.separator + // Folder
imageName + "_s" + df.format(i) + ".tif";
IJ.save(imp, filePath
// image name, three digits, and underscore s
);
filePaths.add(filePath);

}

logger.accept("Export of slice "+slice+" done ("+(i+1)+"/"+slices.size()+")");
});

logger.accept("Export as QuickNii Dataset done - Folder : "+datasetFolder.getAbsolutePath());

return filePaths;
}

// See https://github.com/BIOP/ijp-imagetoatlas/issues/164
/*public static double calculateSaturatedPixelRatio(ImagePlus image) {
if (!(image.getProcessor() instanceof ColorProcessor)) {
return 0;
}
ColorProcessor processor = (ColorProcessor) image.getProcessor();
int width = processor.getWidth();
int height = processor.getHeight();
int saturatedPixelCount = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = processor.getPixel(x, y);
int red = (pixel >> 16) & 0xFF;
int green = (pixel >> 8) & 0xFF;
int blue = pixel & 0xFF;
if (red == 255 || green == 255 || blue == 255) {
saturatedPixelCount++;
}
}
}
double totalPixels = width * height;
double saturatedPixelRatio = saturatedPixelCount / totalPixels;
return saturatedPixelRatio;
}*/

public static class Builder {
File datasetFolder;

Expand Down

1 comment on commit 0cabef8

@imagesc-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.