[Java] Deblur PSF and Wiener - all black result

Hi,

Thanks to OpenCV for the comprehensive and very useful libraries - they’ve enabled me to do some (hobby) work I’ve been planning to do a for a long time.

I’ve create a small proof of concept app in Java with JavaFX, OpenCV 4.5.0_pre, and JRawIO to read jpgs, pngs and NEF files. I’ve successfully followed tutorials and C++ samples to build face detection, FFT, shapening. Im trying now to do PSF and Wiener “deblur”, as per [OpenCV: Out-of-focus Deblur Filter].

However, no matter how much I pore over the code, debug, look at source and tutorials, surf and search this forum and the wider web, I cannot manage to get an image back after the process runs through - all I get back is a black image, no recognisable features of any kind.

I’ve checked for normalisation, ensured DFTs are scaled (or not), have ensured/worked out how to use absdiff() and pow() for the wiener filter code, how to Core.divide and mulSpectrums, but nothing I do or change or investigate produces anything but a full black image result.

I’ve changed PSF to kernels of the same size, looked at filter2D, created extra intermediate mats rather than use them “in place” for some of the calls, and tried to visualise and ensure that the Mats created in calcPSF and calcWiener are what they should be (to me) and it seems that the black image arises when I do the idft() and split().

So, I’m stuck. Can anyone point me in a new direction and happy to show some code if it will help.

Thanks!

i guess, we cannot help, without seing your actual code, so please edit your question, and add it there, thank you.

Start at deblue() then doDeBlur - it calls calcPSF, calcWiener and filter2DFreq
Class these methods are contains instance variables for an arrayList of planes, an imageMat and complexImage - you’ll see calls for getPlanes() etc in various places. Ive include some utility code for completenesss e.g. convertAndNormalize() - these methods are used elsewhere and work successfully.

Thanks again for any insights.

/**

  • do PSF and Wiener deblurring
    */
    public void deblur() {

     // TODO Auto-generated method stub
     long oldTime = System.currentTimeMillis();
     SceneImageUtils.print("Starting to deblur");
             
         if ( null != getImageLocation() && null != getClassifierXmlLocation() ) {
                 
                 updateThisImageMat(true);
                 
                 Mat deblurred = doDeBlur();
                 
                 updateThisDetectedImage( deblurred, getExtension() );
                 
         } else {
                 System.out.println("Null image or classifer xml location, using defaults!");
         }
         SceneImageUtils.print("Finished deblur in (ms) " + (System.currentTimeMillis()-oldTime));
    

}

private void updateThisImageMat(boolean isColour) {

   //@TODO - relaod imageMat - other operations may have manipulatd or reset it
   long oldTime = System.currentTimeMillis();
   if ( isRawFile() ){
           //if loadImage() not already called
           if ( null == getRawReader().getMat()) {
                   setRawReader( SceneImageUtils.getRawReaderFromFile(getImageLocation(), getExtension()) );
           }
           
           if (isColour) {
                   setImageMat( (Mat)getRawReader().getMat() );
           } else {
                   
           }
                   
   } else {
           
           if ( isColour ) {
                   setImageMat( Imgcodecs.imread( imageLocation ) );
           }else {
                   setImageMat( Imgcodecs.imread( getImageLocation(), Imgcodecs.IMREAD_GRAYSCALE ) );
           }
           
   }
   SceneImageUtils.print("Updated image mat in (ms) " + (System.currentTimeMillis()-oldTime));

}

/**

  • calculate a PSF, use to create wiener filter, multiply with BW version of

  • image, convert and normalise

  • @return
    */
    private Mat doDeBlur() {

    Mat imgOut = new Mat();

    // it needs to process even image only
    Rect roi = new Rect(0, 0, (getImageMat().cols() & -2), (getImageMat().rows() & -2) );

    //Hw calculation (start)
    Mat psf = calcPSF( roi.size(), getPsfRadius() );
    Mat filter = calcWienerFilter(psf, (1.0 / getPsfSNR()) );

    //filtering (start, convert to B&W first)
    Mat ImgIn = getBWMat();

    //apply the wiener filter
    imgOut = filter2DFreq( ImgIn.submat(roi), filter );

    // filtering (stop)
    Mat done = convertAndNormalize(imgOut);

    return done;

}

private Mat calcPSF(Size filterSize, int radius)
{

Mat psf = new Mat(filterSize, CvType.CV_32F, new Scalar(0) );
Point centrePoint = new Point(filterSize.width / 2, filterSize.height / 2);

Imgproc.circle(psf, centrePoint, radius, new Scalar(255), -1, 8);
Scalar summa = Core.sumElems(psf);

Mat done = new Mat(filterSize, CvType.CV_32F, new Scalar(0));

Core.divide( summa.val[0], psf, done);

return done;
}

/**
*

  • @param calculatedPSF input PSF as a mat

  • @param invertedSNR - already inverted SNR

  • @return
    */
    private Mat calcWienerFilter( Mat calculatedPSF, double invertedSNR)
    {
    clearPlanesAndTransforms();

    Mat shifted = shiftDFT( calculatedPSF );

    //prep planes for transform
    prepPlanesAndTransforms(shifted);
    mergeAndDFT(false);

    Core.split( getComplexImage(), getPlanes() );

    Mat squaredAbsMat = new Mat(shifted.size(), CvType.CV_32F );

    //java - Mathematical operations on Mat objects OpenCv - Stack Overflow
    Mat absMat = new Mat(shifted.size(), CvType.CV_32F );
    Core.absdiff(getPlanes().get(0), Scalar.all(0), absMat);
    Core.pow(absMat, 2, squaredAbsMat);

    Mat done = new Mat(shifted.size(), CvType.CV_32F );
    Core.add(squaredAbsMat, new Scalar( invertedSNR ), squaredAbsMat);

    Core.divide(getPlanes().get(0), squaredAbsMat, done);

    return done;
    }

private Mat filter2DFreq( Mat inputImg, Mat H)
{

//clear and prep first instance planes and complex images
clearPlanesAndTransforms();
prepPlanesAndTransforms(inputImg);

//merge planes and run DFT so it can be inverted and displayed
mergeAndDFT(true);

// do the filtering
Mat complexIH = multiplyFrequencies(H);

//invert for re-display
invertFFT( complexIH );

return getPlanes().get(0);

}

private Mat getBWMat() {

   Mat greyScaleMat = new Mat();

   if (null != getImageMat() ) {
           greyScaleMat = new Mat(getImageMat().size(), CvType.CV_8UC1 );
           Imgproc.cvtColor(getImageMat(), greyScaleMat, Imgproc.COLOR_BGR2GRAY );
   } else {
           greyScaleMat = null;
   }
   
   return greyScaleMat;

}

private Mat convertAndNormalize(Mat imgOut) {

Mat dst = new Mat();

Core.normalize(imgOut, dst, 0, 255, Core.NORM_MINMAX);

dst.convertTo(dst, CvType.CV_32F);
return dst;
}

/**

  • set detected image to from input Mat, for common formats and NEF raw images
  • @param imageMat
  • @param extension

*/
private void updateThisDetectedImage(Mat imageMat, String extension) {
// TODO Auto-generated method stub
long oldTime = System.currentTimeMillis();
SceneImageUtils.print(“Updating detected image”);

   if ( isRawExtension( extension )) {
           setDetectedImage( ImageConverter.mat2img(imageMat) );
   } else {
           setDetectedImage( ImageConverter.mat2img(imageMat, extension ) );
   }
   
   SceneImageUtils.print("Updated detected image from Mat in (ms)" + (System.currentTimeMillis()-oldTime) );

}

what is the earliest point in your code at which you notice a Mat/image being black when you expect it to have content?

1 Like

Thanks for helping crackwitz.

Just confirmed that it is at the call to calcPSF - if I convertAndNormalize just the output from that call I get a black image, and the same if I convertAndNormalize() the output of calcWienerFilter()

i.e.
Mat psf = calcPSF( roi.size(), getPsfRadius() );
Mat done = convertAndNormalize(psf);

should the psf show up as a (more or less) white circle on a black background if it is displayed?

and to go a little, further (if the thinking is that displaying psf or the wienerFilter result as black is OK), if I delve into filter2DFreq and

  1. display the result of the mergeAndDFT call I see a grey image (a DFT that is not optimeised for display?)
  2. if I display the result of the call to multiplyFrequencies() I see a black image.

Heres the relevant code for those tests

  1. grey image

mergeAndDFT(true);
Core.split(getComplexImage(),getPlanes();
return getPlanes().get(0);

  1. black image

mergeAndDFT(true);
Mat complexIH = multiplyFrequencies(H);
return getPlanes().get(0);

Heres the code for those mergeAndDFt and multiplyFrequencies calls (sorry, I didn’t include in the first sample of code)

private void mergeAndDFT(boolean forInverse) {
// prepare a complex image for performing the dft

Core.merge( getPlanes(), getComplexImage());

// dft it
if (forInverse) {
Core.dft( getComplexImage(), getComplexImage() , Core.DFT_SCALE );

} else {
Core.dft( getComplexImage(), getComplexImage() );
}

}

private Mat multiplyFrequencies(Mat H) {
List newPlanes = new ArrayList<>();

Mat padded = H.clone();
newPlanes.add( padded );
newPlanes.add( Mat.zeros( H.size(), CvType.CV_32F ) );

Mat complexH = new Mat(H.size(), CvType.CV_32F);
Core.merge( newPlanes, complexH );

Mat complexIH = new Mat( getComplexImage().size(), CvType.CV_32F );
Core.mulSpectrums( getComplexImage(), complexH, complexIH, 0);
return complexIH;
}

i’m suspecting a problem with types here, like applying filtering on CV_8U(integer!) images, and thus saturating results to 0.

i see you pre-allocating output Mat’s all over, and you probably expect them to have the type / size you wanted, but quite often, this will be not so, and will deceive you.

e.g, if you use divide() on an uchar image, the result will also will be uchar, and your preallocated float Mat will just be discarded / reallocated to something you did not expect

example:

if at all, type should be CvType.CV_32FC2 (2 channels !)

so:

  • don’t pre-allocate outputs (again, it will only fool you). use new Mat() for output type
  • explicitly convertTo() your input to float as early as possible
  • actually check types after suspicious operations
  • visualize every step in your program
1 Like

thanks Berak, I’ll take your advices and try some things out, and report back. Progress!

A quick change leads to a surprising result - for me at least. Following the idea that I use

new Mat()

my calcPSF function with some logging is now telling me I have an empty Mat for the PSF, is this correct?

FYI, When I inspect the psf object just before the return I see
“Mat [ -1*-1*CV_8UC1, isCont=false, isSubmat=false, nativeObj=0x7f4adc004680, dataAddr=0x0 ]”

private Mat calcPSF(Size filterSize, int radius)
{

Mat psf = new Mat();
Point centrePoint = new Point(filterSize.width / 2, filterSize.height / 2);

Imgproc.circle(psf, centrePoint, radius, new Scalar(255), -1, 8);
Scalar summa = Core.sumElems(psf);

Core.divide( summa.val[0], psf, psf);

SceneImageUtils.print("Empty PSF? : " + psf.empty() );

return psf;
}

sorry for the confusion, i meant the output Mat’s
(from an opencv function, like divide()) before.

here, you still need to properly allocate it, like you had it in the prev. version:

Mat psf = new Mat(filterSize, CvType.CV_32F, new Scalar(0) );

ok, thanks, appreciate your continued attention!

Just to let you know Ive confirmed so far
I can visualise the calcPSF output Mat
Cant visualise the calcWiener output Mat - I see black image but expect, to see something else that would combine with the image in some way
Confirm that dft and idft work as expected.

Have followed advice and tried variations in places, but still not getting a wiener function processed image as output. Haven’t given up yet though, but will take more time now to try and resolve. A break and fresh eyes may help after all!

More work refactoring means I think I can say that the Mat multiplication code I have is causing the issue (or the code that generates the input Wiener filter - which I still cannot visualise). I am banging my head against a wall though I feel, as no amount of switching Mat creation methods or chaining together (or not) intermediate objects seems to be helping me get closer to resolving.

I have since done a build of opencv 4.5.1 in order to see if the sample "example_tutorial_out_of_focus_deblur_filter " code works, but it is giving me either a core dump with a png file, or an “ERROR : Image cannot be loaded…!!” with jpg files.

i.e.

./example_tutorial_out_of_focus_deblur_filter -image=./eve.jpg
2018-07-12
DeBlur_v8
You will learn how to recover an out-of-focus image by Wiener filter
ERROR : Image cannot be loaded…!!

or

./example_tutorial_out_of_focus_deblur_filter -image=./lena.png
2018-07-12
DeBlur_v8
You will learn how to recover an out-of-focus image by Wiener filter
Segmentation fault (core dumped)

valgrind on the lena.png call shows the following:

==52144== Use of uninitialised value of size 8
==52144== at 0x77E6126: jpeg_CreateCompress (in /usr/lib/libjpeg.so.8.2.2)
==52144== by 0x486D859: cv::JpegEncoder::write(cv::Mat const&, std::vector<int, std::allocator > const&) (in /home/name/git/opencv_4.5.0_pre/build/lib/libopencv_imgcode
cs.so.4.5.1)
==52144== by 0x486310F: cv::imwrite(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, cv::_InputArray const&, std::vector<int, std::allo
cator > const&) (in /home/name/git/opencv_4.5.0_pre/build/lib/libopencv_imgcodecs.so.4.5.1)
==52144== by 0x10AA72: main (in /home/name/git/opencv_4.5.0_pre/build/bin/example_tutorial_out_of_focus_deblur_filter)
==52144==
==52144== Invalid write of size 4
==52144== at 0x77E6126: jpeg_CreateCompress (in /usr/lib/libjpeg.so.8.2.2)
==52144== by 0x486D859: cv::JpegEncoder::write(cv::Mat const&, std::vector<int, std::allocator > const&) (in /home/name/git/opencv_4.5.0_pre/build/lib/libopencv_imgcode
cs.so.4.5.1)
==52144== by 0x486310F: cv::imwrite(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, cv::_InputArray const&, std::vector<int, std::allo
cator > const&) (in /home/name/git/opencv_4.5.0_pre/build/lib/libopencv_imgcodecs.so.4.5.1)
==52144== by 0x10AA72: main (in /home/name/git/opencv_4.5.0_pre/build/bin/example_tutorial_out_of_focus_deblur_filter)
==52144== Address 0x679 is not stack’d, malloc’d or (recently) free’d
==52144==
==52144==
==52144== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==52144== Access not within mapped region at address 0x679
==52144== at 0x77E6126: jpeg_CreateCompress (in /usr/lib/libjpeg.so.8.2.2)
==52144== by 0x486D859: cv::JpegEncoder::write(cv::Mat const&, std::vector<int, std::allocator > const&) (in /home/name/git/opencv_4.5.0_pre/build/lib/libopencv_imgcode
cs.so.4.5.1)
==52144== by 0x486310F: cv::imwrite(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, cv::_InputArray const&, std::vector<int, std::allo
cator > const&) (in /home/name/git/opencv_4.5.0_pre/build/lib/libopencv_imgcodecs.so.4.5.1)
==52144== by 0x10AA72: main (in /home/name/git/opencv_4.5.0_pre/build/bin/example_tutorial_out_of_focus_deblur_filter)

The image files are:

file ./eve.jpg
./eve.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 300x300, segment length 16, Exif Standard: [TIFF image data, little-endian, direntries=13, manufacturer
=Nokia, model=N70-1, orientation=upper-left, xresolution=182, yresolution=190, resolutionunit=2, software=darktable 3.2.1, datetime=2020:12:30 11:57:42], baseline, precision 8,
1024x768, components 3

and

file ./lena.png
./lena.png: PNG image data, 512 x 512, 8-bit/color RGB, non-interlaced

NB: I suspect the cause of the problem (from the valgrind output) here is that during the build I had errors with various .so, for example:

/usr/lib/x86_64-linux-gnu/libjpeg.so

and other libs for png, webp, tiff etc.
I created symlinks to the relevant libs in /usr/lib in order to get the build to complete.

But why when running with lena.png is libjpeg.so being used? Why is the jpg file not loading? (I created both files with Darktable, converting from colour versions).

I am running Manjaro 20.1

Linux host 5.8.18-1-MANJARO #1 SMP PREEMPT Sun Nov 1 14:10:04 UTC 2020 x86_64 GNU/Linux

a problem reading simple png/jpeg files? that’s curious! I’ve never actually had any problems with OpenCV reading picture files, but others sometimes do. I would agree with your determination that it’s some “DLL hell” situation.

OpenCV likely loads any and all libraries regardless of actual use. and in your case it seems to pick up the wrong shared objects.

it is peculiar. I checked with ldd the linked libraries for the java native lib I reference in eclipse for java development and the sample program - and they are the same. Some extra logging in the sample indeed shows that the jpg file after imread is empty, and with the png file, processing continues until the attempt to write the result.jpg file.

I will keep looking.

FYI, I turned WITH_JPEG and WITH_PNG off and BUILD_JPEG and BUILD_PNG on and rebuilt. Now the code doesn’t load either jpeg or png files!

Other samples like porting_anisotropic_image_segmentation_gapi.cpp that load a jpeg and BasicLinearTransformsTrackbar also fail. The former with the same

ERROR : Image cannot be loaded…!!

and the latter with

what(): OpenCV(4.5.1-pre) /home/ultan/git/opencv_4.5.0_pre/modules/highgui/src/window.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in function ‘imshow’

Aborted (core dumped)

I give up now!

I installed Ubuntu 20.10 in Virtualbox, download the latest git code, ran a build (only inlcuded samples to be built - everything else the default build) and executed the sample code again, and I still get the error that it cannot read the jpg or png files I give it.

My version_string is:

“\n”
“General configuration for OpenCV 4.5.1-dev =====================================\n”
" Version control: 4.5.1-35-gbec7b297ed\n"
“\n”
" Platform:\n"
" Timestamp: 2020-12-30T22:13:36Z\n"
" Host: Linux 5.8.0-33-generic x86_64\n"
" CMake: 3.16.3\n"
" CMake generator: Unix Makefiles\n"
" CMake build tool: /usr/bin/gmake\n"
" Configuration: Release\n"
“\n”
" CPU/HW features:\n"
" Baseline: SSE SSE2 SSE3\n"
" requested: SSE3\n"
" Dispatched code generation: SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX\n"
" requested: SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX\n"
" SSE4_1 (17 files): + SSSE3 SSE4_1\n"
" SSE4_2 (2 files): + SSSE3 SSE4_1 POPCNT SSE4_2\n"
" FP16 (1 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX\n"
" AVX (5 files): + SSSE3 SSE4_1 POPCNT SSE4_2 AVX\n"
" AVX2 (31 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2\n"
" AVX512_SKX (7 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_COMMON AVX512_
SKX\n"
“\n”
" C/C++:\n"
" Built as dynamic libs?: YES\n"
" C++ standard: 11\n"
" C++ Compiler: /usr/bin/c++ (ver 10.2.0)\n"
" C++ flags (Release): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=ad
dress -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpoint
er-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wim
plicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer
-ffunction-sections -fdata-sections -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -D
NDEBUG -DNDEBUG\n"
" C++ flags (Debug): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=ad
dress -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpoint
er-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wim
plicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer
-ffunction-sections -fdata-sections -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -g -O
0 -DDEBUG -D_DEBUG\n"
" C Compiler: /usr/bin/cc\n"
" C flags (Release): -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-po
int -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Wi
nit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fd
iagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -msse -
msse2 -msse3 -fvisibility=hidden -O3 -DNDEBUG -DNDEBUG\n"
" C flags (Debug): -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-po
int -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Wi
nit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fd
iagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -msse -
msse2 -msse3 -fvisibility=hidden -g -O0 -DDEBUG -D_DEBUG\n"
" Linker flags (Release): -Wl,–exclude-libs,libippicv.a -Wl,–exclude-libs,libippiw.a -Wl,–gc-sectio
ns -Wl,–as-needed \n"
" Linker flags (Debug): -Wl,–exclude-libs,libippicv.a -Wl,–exclude-libs,libippiw.a -Wl,–gc-sectio
ns -Wl,–as-needed \n"
" ccache: NO\n"
" Precompiled headers: NO\n"
" Extra dependencies: dl m pthread rt\n"
" 3rdparty dependencies:\n"
“\n”
" OpenCV modules:\n"
" To be built: calib3d core dnn features2d flann gapi highgui imgcodecs imgproc ml objdetect
photo stitching ts video videoio\n"
" Disabled: world\n"
" Disabled by dependency: -\n"
" Unavailable: java python2 python3\n"
" Applications: tests perf_tests examples apps\n"
" Documentation: NO\n"
" Non-free algorithms: NO\n"
“\n”
" GUI: \n"
" GTK+: NO\n"
" VTK support: NO\n"
“\n”
" Media I/O: \n"
" ZLib: zlib (ver 1.2.11)\n"
" JPEG: libjpeg-turbo (ver 2.0.6-62)\n"
" WEBP: build (ver encoder: 0x020f)\n"
" PNG: build (ver 1.6.37)\n"
" TIFF: build (ver 42 - 4.0.10)\n"
" JPEG 2000: build (ver 2.3.1)\n"
" OpenEXR: build (ver 2.3.0)\n"
" HDR: YES\n"
" SUNRASTER: YES\n"
" PXM: YES\n"
" PFM: YES\n"
“\n”
" Video I/O:\n"
" DC1394: NO\n"
" FFMPEG: NO\n"
" avcodec: NO\n"
" avformat: NO\n"
" avutil: NO\n"
" swscale: NO\n"
" avresample: NO\n"
" GStreamer: NO\n"
" v4l/v4l2: YES (linux/videodev2.h)\n"
“\n”
" Parallel framework: pthreads\n"
“\n”
" Trace: YES (with Intel ITT)\n"
“\n”
" Other third-party libraries:\n"
" Intel IPP: 2020.0.0 Gold [2020.0.0]\n"
" at: /home/name/git/opencv/build/3rdparty/ippicv/ippicv_lnx/icv\n"
" Intel IPP IW: sources (2020.0.0)\n"
" at: /home/name/git/opencv/build/3rdparty/ippicv/ippicv_lnx/iw\n"
" Lapack: NO\n"
" Eigen: NO\n"
" Custom HAL: NO\n"
" Protobuf: build (3.5.1)\n"
“\n”
" OpenCL: YES (no extra features)\n"
" Include path: /home/name/git/opencv/3rdparty/include/opencl/1.2\n"
" Link libraries: Dynamic load\n"
“\n”
" Python (for build): /usr/bin/python3\n"
“\n”
" Java: \n"
" ant: NO\n"
" JNI: NO\n"
" Java wrappers: NO\n"
" Java tests: NO\n"
“\n”
" Install to: /usr/local\n"
“-----------------------------------------------------------------\n”
“\n”

the code on the deblur tutorial page?

try the simplest possible code that only contains imread, and maybe imshow and waitKey. hardcode the path to the file.

Thanks for helping.

Bizarrely - I wrote the simple code you suggested and it worked - but the only thing that I effectively changed was the directory where the jpg was (I copied the code from the main() of the out_of_focus_deblur_filter and simplified it with hardcoded path, imread and imwrite).

In the case where it doesn’t work it is in ~/Pictures. In the case where it does work, it is in the same dir where the built executable is (~/git/opencv/build/bin). The jpg in each dir has the same user:group and permissions (744). The out_of_focus_deblur_filter code also works where the jpg is in the same directory as the executable.

This is in my fresh ubuntu install. In Manjaro this test does not work at all.

Ubuntu is

Linux hostname 5.8.0-33-generic #36-Ubuntu SMP Wed Dec 9 09:14:40 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Manjaro is

Linux hostname 5.9.16-1-MANJARO #1 SMP PREEMPT Mon Dec 21 22:00:46 UTC 2020 x86_64 GNU/Linux

In any case, this just proves that my java code should work and its not a platform or library thing (I can read jpgs with imread in java OK, its the wiener code Ive written thats messing things up).

Happy New Year by the way, I hope I don’t get any responses from you tonight or tomorrow, and I appreciate your attention today!

say, are you literally giving the path as “~/Pictures/…”?

the ~ is a special thing that needs to be explicitly resolved. it doesn’t “just work”. shells do that automatically but it’s not an integral notion of file systems.