How to override a code in standard python library? - scikit-image

while executing the model.fit_generator code in my python image processing program, I came across this error "/opt/conda/lib/python3.6/site-packages/skimage/exposure/exposure.py:351: RuntimeWarning: invalid value encountered in true_divide
image = (image - imin) / float(imax - imin)"
I need to know how can I override the code in skimage/exposure.py so that I can get past the error. I know what the new code should look like in skimage/exposure.py but I don't know how to override the module in my python 3.6 program.
I tried copying the entire code of skimage/exposure.py in my python program and put in my piece of code but it did not get picked up and I ended up getting the error again.
skimage/exposure.py has this code
if imin != imax:
image = (image - imin) / float(imax - imin)
I want to override it into my program as
if imax != imin:
image = (image - imin)/float(imax - imin)
else:
image = image - imin
I want to know how I can override the skimage/exposure.py code in my python program.

Related

find template image in directory of images

I have a directory of images and an image that I know is in this image directory there is a similar image in the directory saved in a different format and scaled differently, but I dont know where (about 100 000 images).
I want to look for the image and find out its filename inside this directory.
I am looking for a mostly already made soulution which I couldn't find. I found OpenCV but I would need to write code around that. Is there a project like that out there?
If there isn't could you help me make a simple C# console app using OpenCV, I tried their templates but never managed to get SURF or CudaSURF working.
Thanks
Edited as per #Mark Setchell's comment
If the image is identical, the fastest way is to get the file size of the image you are looking for and compare it with the file sizes of the images amongst which you are searching.
I suggest this first because, as Christoph clarifies in the comments, it doesn't require reading the file at all - it is just metadata.
If that yields more than one matching answer, calculate a hash (MD5 or other) and pick the filename that produces the same hash.
Again, as mentioned by Christoph in the comments, this doesn't require decoding the image, or holding the decompressed image in RAM, just checksumming it.
So in the end I used this site and modified the python code used there for searching a directory instead of a single image. There is not much code so the full thing is below:
import argparse
from ast import For, arg
import cv2
from os import listdir
from os.path import isfile, join
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str, required=True,
help="path to input image where we'll apply template matching")
ap.add_argument("-t", "--template", type=str, required=True,
help="path to template image")
args = vars(ap.parse_args())
# load the input image and template image from disk
print("[INFO] loading template...")
template = cv2.imread(args["template"])
cv2.namedWindow("Output")
cv2.startWindowThread()
# Display an image
cv2.imshow("Output", template)
cv2.waitKey(0)
# convert both the image and template to grayscale
templateGray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
imageFileNames = [f for f in listdir(args["image"]) if isfile(join(args["image"], f))]
for imageFileName in imageFileNames:
try:
imagePath = args["image"] + imageFileName
print("[INFO] Loading " + imagePath + " from disk...")
image = cv2.imread(imagePath)
print("[INFO] Converting " + imageFileName + " to grayscale...")
imageGray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print("[INFO] Performing template matching for " + imageFileName + "...")
result = cv2.matchTemplate(imageGray, templateGray,
cv2.TM_CCOEFF_NORMED)
(minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(result)
(startX, startY) = maxLoc
endX = startX + template.shape[1]
endY = startY + template.shape[0]
if maxVal > 0.75:
print("maxVal = " + str(maxVal))
# draw the bounding box on the image
cv2.rectangle(image, (startX, startY), (endX, endY), (255, 0, 0), 3)
# show the output image
cv2.imshow("Output", image)
cv2.waitKey(0)
cv2.imshow("Output", template)
except KeyboardInterrupt:
break
except:
print(imageFileName)
print("Error")
cv2.destroyAllWindows()
The code above shows any image with match value (what I guess is how much similarity there is between source and template) greater than 0.75
Probably still too low but if you want to use it tweak it to your liking.
Note that this WILL NOT work if the image is rotated and if, like me, you have a bright light source in the template other lightsources will come up as false positives
As for time it took me about 7 hours, where the script paused about every 20 minutes for a false positive until I found my image. I got through about 2/3 of all images.
as a sidenote it took 10 minutes to just build the array of files inside the directory, and it took about 500mb of ram once done
This is not the best answer so if anyone more qualified finds this feel free to write another answer.

Writing Macro in ImageJ to open, change color, adjust brightness and resave microscope images

I'm trying to write a code in Image J that will:
Open all images in separate windows that contains "488" within a folder
Use look up tables to convert images to green and RGB color From ImageJ, the commands are: run("Green"); and run("RGB Color");
Adjust the brightness and contrast with defined values for Min and Max (same values for each image).
I know that the code for that is:
//run("Brightness/Contrast..."); setMinAndMax(value min, value max); run("Apply LUT");
Save each image in the same, original folder , in Tiff and with the same name but finishing with "processed".
I have no experience with Java and am very bad with coding. I tried to piece something together using code I found on stackoverflow and on the ImageJ website, but kept getting error codes. Any help is much appreciated!
I don't know if you still need it, but here is an example.
output_dir = "C:/Users/test/"
input_dir = "C:/Users/test/"
list = getFileList(input_dir);
listlength = list.length;
setBatchMode(true);
for (z = 0; z < listlength; z++){
if(endsWith(list[z], 'tif')==true ){
if(list[z].contains("488")){
title = list[z];
end = lengthOf(title)-4;
out_path = output_dir + substring(title,0,end) + "_processed.tif";
open(input_dir + title);
//add all the functions you want
run("Brightness/Contrast...");
setMinAndMax(1, 15);
run("Apply LUT");
saveAs("tif", "" + out_path + "");
close();
};
run("Close All");
}
}
setBatchMode(false);
I think it contains all the things you need. It opens all the images (in specific folder) that ends with tif and contains 488. I didn't completely understand what you want to do with each photo, so I just added your functions. But you probably won't have problems with adding more/different since you can get them with macro recorder.
And the code is written to open tif files. If you have tiff just be cerful that you change that and also change -4 to -5.

Pillow: converting a TIFF from greyscale 16 bit to 8 bit results in fully white image

I know that there are multiple similar questions on SO, but I have tried multiple proposed solutions to no avail.
I have the following TIFF image that opens in Pillow as type='I;16'.
Google Drive link
Based on this SO question, I wrote this code to convert it:
def tiff_force_8bit(image, **kwargs):
if image.format == 'TIFF' and image.mode == 'I;16':
array = np.array(image)
normalized = (array.astype(np.uint16) - array.min()) * 255.0 / (array.max() - array.min())
image = Image.fromarray(normalized.astype(np.uint8))
return image
However, the result is a completely white image.
I have tried other solutions too, such as this:
table = [i/256 for i in range(65536)]
image = image.point(table, 'L')
with the same result: full white out.
Can anyone shed some light?
Thanks!
There's nothing wrong with your code. If you run:
# Open image
im = Image.open('NGC 281 11-01-2021 Ha 1.15.tif')
# Force to 8-bit
res = tiff_force_8bit(im)
# Check min and max of result
res.getextrema() # prints (0,255) as expected
# Save as PNG
res.save('result.png')
# Display it
res.show()
I can only guess there is a problem with your installation or the way you display the result.

Working on more than one image in Matlab

I started to learn Matlab newly. I am trying to learn about classification. I will make classification for my 23 images. In my function file I am using
I = imread('img.jpg');
a = rgb2gray(I);
bw = double(imread('mask_img.jpg'))/255;
b = rgb2gray(bw);
bwi = 1-b;
And working on the original image and ground truth of the image. I can handle one image and I have loop in the my main file.
for i=1:original_images_db.Count
original = original_images_db.ImageLocation(i);
groundtruth = original_file;
[x,y] = calculateFeatures(original, groundtruth, parameters);
dataset.HorizonFeats{i} = features;
end
And i related original_images_db with imageset to files. When i run my main file, naturally everytime it reads img from function file but actually in command file main can detect other images. My question is how can i make a loop in my function file so my data can be in all other images?
Thank you
fname={'1.jpg','2.jpg','3.jpg'};
create cell like that, it contains all file-path of images
for i=1: length(fname)
im= imread(fname{i});
end
and now you can iterate the all images
or
use dir(image_path) function
fnames = dir('image_directory_path');

kivy: possible to use buffer as image source?

I've got code along the lines of the following which generates a new image out of some existing images.
from PIL import Image as pyImage
def create_compound_image(back_image_path, fore_image_path, fore_x_position):
back_image_size = get_image_size(back_image_path)
fore_image_size = get_image_size(fore_image_path)
new_image_width = (fore_image_size[0] / 2) + back_image_size[0]
new_image_height = fore_image_size[1] + back_image_size[1]
new_image = create_new_image_canvas(new_image_width, new_image_height)
back_image = pyImage.open(back_image_path)
fore_image = pyImage.open(fore_image_path)
new_image.paste(back_image, (0, 0), mask = None)
new_image.paste(fore_image, (fore_x_position, back_image_size[1]), mask = None)
return new_image
Later in the code, I've got something like this:
from kivy.uix.image import Image
img = Image(source = create_compound_image(...))
If I do the above, I get the message that Image.source only accepts string/unicode.
If I create a StringIO.StringIO() object from the new image, and try to use that as the source, the error message is the same as above. If I use the output of the StringIO object's getvalue() method as the source, the message is that the source must be encoded string without NULL bytes, not str.
What is the proper way to use the output of the create_compound_image() function as the source when creating a kivy Image object?
It seems you want to just combine two images into one, you can actually just create a texture using Texture.create and blit the data to a particular pos using Texture.blit_buffer .
from kivy.core.image import Image
from kivy.graphics import Texture
bkimg = Image(bk_img_path)
frimg = Image(fr_img_path)
new_size = ((frimg.texture.size[0]/2) + bkimg.texture.size[0],
frimg.texture.size[1] + bkimg.texture.size[1])
tex = Texture.create(size=new_size)
tex.blit_buffer(pbuffer=bkimg.texture.pixels, pos=(0, 0), size=bkimg.texture.size)
tex.blit_buffer(pbuffer=frimg.texture.pixels, pos=(fore_x_position, bkimg.texture.size[1]), size=frimg.texture.size)
Now you can use this texture anywhere directly like::
from kivy.uix.image import Image
image = Image()
image.texture = tex
source is a StringProperty and is expecting a path to file. That's why you got errors when you tried to pass PIL.Image object, StringIO object or string representation of image. It's not what framework wants. As for getting image from StringIO, it was discussed before here:
https://groups.google.com/forum/#!topic/kivy-users/l-3FJ2mA3qI
https://github.com/kivy/kivy/issues/684
You can also try much simpler, quick and dirty method - just save your image as a tmp file and read it normal way.

Resources