Now the grayscale morphology in estimate_white is performed in a reasonable time.
The performance improvement is obtained by using opencv's gray morphology operators instad of imagej's
This commit is contained in:
parent
74d7f9e603
commit
1fd2fc4281
|
@ -79,6 +79,22 @@ from org.bytedeco.javacpp.opencv_imgcodecs import imread, imwrite # pylint: dis
|
|||
# from org.bytedeco.javacpp.opencv_core import CvMat
|
||||
|
||||
|
||||
def print_ijopencvmat(src_mat):
|
||||
"""Print details about the given opencv Mat object
|
||||
|
||||
:param org.bytedeco.javacpp.opencv_core.Mat src_mat:
|
||||
"""
|
||||
# Mat members listed in javacpp-presets/opencv/src/gen/java/org/bytedeco/opencv/opencv_core/Mat.java
|
||||
print("number of rows : %d" % src_mat.rows())
|
||||
print("number of columns : %d" % src_mat.cols())
|
||||
print("number of dimensions : %d" % src_mat.dims())
|
||||
size = src_mat.size()
|
||||
print("size : %d, %d" % (size.get(0), size.get(1)))
|
||||
print("number of channels: %d" % src_mat.channels())
|
||||
print("pixel type : %d" % src_mat.type())
|
||||
|
||||
|
||||
|
||||
def test_opencv_calc_hist1():
|
||||
src_image = opencv_core.Mat([128, 128])
|
||||
histogram = opencv_imgproc.cvCalcHist(src_image) # pylint: disable=unused-variable
|
||||
|
@ -199,6 +215,28 @@ def test_ijopencv_converter():
|
|||
# white_mat = imread(white_image_file_path)
|
||||
print('mat', mat)
|
||||
|
||||
def test_ijopencv_morphology_ex():
|
||||
print(opencv_core.CV_VERSION())
|
||||
# src_image = opencv_core.Mat(128, 128)
|
||||
src_image = opencv_core.Mat().zeros(96, 128, opencv_core.CV_8U).asMat()
|
||||
print(src_image)
|
||||
|
||||
struct_el_size = opencv_core.Size(3, 3)
|
||||
struct_el_anchor = opencv_core.Point(1, 1)
|
||||
# print(struct_el_anchor)
|
||||
struct_element = opencv_imgproc.getStructuringElement(opencv_imgproc.MORPH_RECT, struct_el_size, struct_el_anchor)
|
||||
print(struct_element)
|
||||
# dst_image = opencv_core.Mat().zeros(128, 128, opencv_core.CV_8U).asMat()
|
||||
dst_image = opencv_core.Mat(src_image.size(), src_image.type())
|
||||
|
||||
# warning ! trying to guess the arguments from opencv's documentation is time consuming as the error messages are misleading (in the following call, javacpp complains that the 1st argument is not a org.bytedeco.javacpp.opencv_core$Mat, while it is ! The problem comes from the order of the arguments). So, instead of guessing, the found accepted signatures of morphologyEx are in javacpp-presets/opencv/src/gen/java/org/bytedeco/opencv/global/opencv_imgproc.java
|
||||
# opencv_imgproc.morphologyEx(src_image, opencv_imgproc.MORPH_OPEN, struct_element, dst_image)
|
||||
# TypeError: morphologyEx(): 1st arg can't be coerced to org.bytedeco.javacpp.opencv_core$GpuMat, org.bytedeco.javacpp.opencv_core$Mat, org.bytedeco.javacpp.opencv_core$UMat
|
||||
|
||||
opencv_imgproc.morphologyEx(src_image, dst_image, opencv_imgproc.MORPH_OPEN, struct_element)
|
||||
print_ijopencvmat(dst_image)
|
||||
|
||||
|
||||
|
||||
def test_opencv():
|
||||
|
||||
|
@ -206,6 +244,9 @@ def test_opencv():
|
|||
|
||||
test_opencv_calc_hist()
|
||||
|
||||
test_ijopencv_morphology_ex()
|
||||
|
||||
|
||||
|
||||
# If a Jython script is run, the variable __name__ contains the string '__main__'.
|
||||
# If a script is loaded as module, __name__ has a different value.
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
from imageengine import IImage, IImageEngine
|
||||
from ij import IJ
|
||||
from ij.plugin import ImageCalculator
|
||||
from ijopencv.ij import ImagePlusMatConverter # pylint: disable=import-error
|
||||
from ijopencv.opencv import MatImagePlusConverter # pylint: disable=import-error
|
||||
import org.bytedeco.javacpp.opencv_core as opencv_core # pylint: disable=import-error
|
||||
import org.bytedeco.javacpp.opencv_imgproc as opencv_imgproc # pylint: disable=import-error
|
||||
# from org.bytedeco.javacpp.opencv_imgcodecs import imread, imwrite # pylint: disable=import-error
|
||||
|
||||
|
||||
class IJImage(IImage):
|
||||
|
||||
|
@ -37,6 +43,79 @@ def imagej_run_image_command(image, command, options):
|
|||
raise Exception('The command "%s" with options "%s" failed because of the following error : %s' % (command, options, error_message))
|
||||
|
||||
|
||||
def perform_gray_morphology_with_imagej(image, operator, structuring_element_shape, structuring_element_radius):
|
||||
"""
|
||||
:param IJImage image:
|
||||
:param str operator: eg 'open'
|
||||
:param str structuring_element_shape: eg 'square'
|
||||
:param int structuring_element_radius:
|
||||
"""
|
||||
assert operator not in ['fast open', 'fast erode'], "as of 13/09/2019, fast operators such as 'fast erode' seem broken in fiji (the resulting image is not at all similar to their slow equivalent)"
|
||||
|
||||
processor = image.ij_image.getProcessor()
|
||||
convert_to_byte = False
|
||||
if processor.getBitDepth() != 8:
|
||||
convert_to_byte = True
|
||||
min_value = processor.getMin()
|
||||
max_value = processor.getMax()
|
||||
print("warning: downgrading image to byte as imagej's Gray Morphology processing doesn't handle 16bit images (range=[%d, %d])" % (min_value, max_value))
|
||||
do_scaling = True
|
||||
image.ij_image.setProcessor(processor.convertToByte(do_scaling))
|
||||
print("before gray morphology")
|
||||
assert structuring_element_radius < 11, "the radius of the structuring element is too big (%d); using it with Fiji's 'Gray Morphology' tool would result in very long computations." % structuring_element_radius
|
||||
imagej_run_image_command(image.ij_image, "Gray Morphology", "radius=%d type=%s operator=%s" % (structuring_element_radius, structuring_element_shape, operator))
|
||||
print("after gray morphology")
|
||||
|
||||
|
||||
def perform_gray_morphology_with_ijopencv(image, operator, structuring_element_shape, structuring_element_radius):
|
||||
"""Perform gray morphology on the given image using imagej's opencv api (this api is provided by javacpp-presets)
|
||||
|
||||
:param IJImage image:
|
||||
:param str operator: eg 'open'
|
||||
:param str structuring_element_shape: eg 'square'
|
||||
:param int structuring_element_radius:
|
||||
"""
|
||||
|
||||
shape_name_to_opencv_id = {
|
||||
'square': opencv_imgproc.MORPH_RECT,
|
||||
}
|
||||
|
||||
operator_name_to_opencv_id = {
|
||||
'open': opencv_imgproc.MORPH_OPEN,
|
||||
'close': opencv_imgproc.MORPH_CLOSE,
|
||||
}
|
||||
|
||||
if structuring_element_shape not in shape_name_to_opencv_id.keys():
|
||||
raise NotImplementedError('structuring element shape %s is not currently supported (supported operators : %s)' % (structuring_element_shape, str(operator_name_to_opencv_id.keys())))
|
||||
|
||||
if operator not in operator_name_to_opencv_id.keys():
|
||||
raise NotImplementedError('operator %s is not currently supported (supported operators : %s)' % (operator, str(operator_name_to_opencv_id.keys())))
|
||||
|
||||
imp2mat = ImagePlusMatConverter()
|
||||
cv_src_image = imp2mat.toMat(image.ij_image.getProcessor())
|
||||
|
||||
# cv_src_image = opencv_core.Mat().zeros(128, 128, opencv_core.CV_8U).asMat()
|
||||
print(cv_src_image)
|
||||
|
||||
struct_el_size = structuring_element_radius * 2 + 1
|
||||
|
||||
struct_el_size = opencv_core.Size(struct_el_size, struct_el_size)
|
||||
struct_el_anchor = opencv_core.Point(structuring_element_radius, structuring_element_radius)
|
||||
# print(struct_el_anchor)
|
||||
struct_element = opencv_imgproc.getStructuringElement(shape_name_to_opencv_id[structuring_element_shape], struct_el_size, struct_el_anchor)
|
||||
print(struct_element)
|
||||
# dst_image = opencv_core.Mat().zeros(128, 128, opencv_core.CV_8U).asMat()
|
||||
cv_dst_image = opencv_core.Mat(cv_src_image.size(), cv_src_image.type())
|
||||
|
||||
# warning ! trying to guess the arguments from opencv's documentation is time consuming as the error messages are misleading (in the following call, javacpp complains that the 1st argument is not a org.bytedeco.javacpp.opencv_core$Mat, while it is ! The problem comes from the order of the arguments). So, instead of guessing, the found accepted signatures of morphologyEx are in javacpp-presets/opencv/src/gen/java/org/bytedeco/opencv/global/opencv_imgproc.java
|
||||
# opencv_imgproc.morphologyEx(cv_src_image, opencv_imgproc.MORPH_OPEN, struct_element, dst_image)
|
||||
# TypeError: morphologyEx(): 1st arg can't be coerced to org.bytedeco.javacpp.opencv_core$GpuMat, org.bytedeco.javacpp.opencv_core$Mat, org.bytedeco.javacpp.opencv_core$UMat
|
||||
print('before opencv_imgproc.morphologyEx')
|
||||
opencv_imgproc.morphologyEx(cv_src_image, cv_dst_image, operator_name_to_opencv_id[operator], struct_element)
|
||||
print('after opencv_imgproc.morphologyEx')
|
||||
|
||||
mat2imp = MatImagePlusConverter()
|
||||
image.ij_image.setProcessor(mat2imp.toImageProcessor(cv_dst_image))
|
||||
|
||||
|
||||
class IJImageEngine(IImageEngine):
|
||||
|
@ -72,21 +151,8 @@ class IJImageEngine(IImageEngine):
|
|||
:param str structuring_element_shape: eg 'square'
|
||||
:param int structuring_element_radius:
|
||||
"""
|
||||
assert operator not in ['fast open', 'fast erode'], "as of 13/09/2019, fast operators such as 'fast erode' seem broken in fiji (the resulting image is not at all similar to their slow equivalent)"
|
||||
|
||||
processor = image.ij_image.getProcessor()
|
||||
convert_to_byte = False
|
||||
if processor.getBitDepth() != 8:
|
||||
convert_to_byte = True
|
||||
min_value = processor.getMin()
|
||||
max_value = processor.getMax()
|
||||
print("warning: downgrading image to byte as imagej's Gray Morphology processing doesn't handle 16bit images (range=[%d, %d])" % (min_value, max_value))
|
||||
do_scaling = True
|
||||
image.ij_image.setProcessor(processor.convertToByte(do_scaling))
|
||||
print("before gray morphology")
|
||||
assert structuring_element_radius < 11, "the radius of the structuring element is too big (%d); using it with Fiji's 'Gray Morphology' tool would result in very long computations." % structuring_element_radius
|
||||
imagej_run_image_command(image.ij_image, "Gray Morphology", "radius=%d type=%s operator=%s" % (structuring_element_radius, structuring_element_shape, operator))
|
||||
print("after gray morphology")
|
||||
# we use opencv version because imagej's slow version is way too slow for big values of structuring_element_radius
|
||||
perform_gray_morphology_with_ijopencv(image, operator, structuring_element_shape, structuring_element_radius)
|
||||
|
||||
|
||||
def replace_border(self, image, band_width):
|
||||
|
|
|
@ -264,7 +264,7 @@ def test_preprocessing(raw_images_root_path):
|
|||
IImageEngine.set_instance(IJImageEngine())
|
||||
catalog = ImageCatalog(raw_images_root_path)
|
||||
sequence = catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos2']
|
||||
white_estimator = WhiteEstimator(open_size=3, close_size=3, average_size=3)
|
||||
white_estimator = WhiteEstimator(open_size=75, close_size=75, average_size=75)
|
||||
white_estimate = white_estimator.estimate_white([sequence], ['DM300_327-353_fluo'])
|
||||
# find_white_reference_image(white_estimate, sequence.get_white())
|
||||
print(white_estimate)
|
||||
|
|
Loading…
Reference in New Issue