Repository: opencv
Issue: BOWKMeansTrainer Java API SIGSEGV on cluster()
Labels: priority: low,category: features2d,category: java bindings

##### System information (version)
- OpenCV => 3.3.1
- Operating System / Platform => Debian Linux 64bit
- Compiler => GCC

##### Detailed description

I am trying to create a BOW dictionary from a pre-computed set of SIFT descriptors. 
The SIFT descriptors are limited to max 1750 features. 

Regardless of whether I use add() to add the descriptor, or whether I create my own Mat and call cluster with this mat both produce the same error.

The output from my program is:

```Creating BOVW
  + Database size = 16296
  + Loading IDs
  + Nominal training image count = 1000
  + Actual expected training image count = 1018
  + Step size = 16
  + Loading Descriptors
  + Loaded 0 (0.00%)
  + Loaded 200 (19.65%)
  + Loaded 400 (39.29%)
  + Loaded 600 (58.94%)
  + Loaded 800 (78.59%)
  + Loaded 1000 (98.23%)
  + TOTAL Training image descriptors loaded = 1017 (ignored 1)

  + Dictionary size = 10000
  + Clustering
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f5bf827565c, pid=7558, tid=0x00007f5c585e9700
#
# JRE version: OpenJDK Runtime Environment (8.0_151-b12) (build 1.8.0_151-8u151-b12-1-b12)
# Java VM: OpenJDK 64-Bit Server VM (25.151-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [opencv-3.3.1-linux_x86-64.so+0x3b165c]  Java_org_opencv_features2d_BOWKMeansTrainer_cluster_11+0x1c
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/barrypearce/workspace/imgtestrun/bsip-imgtest-1.0/hs_err_pid7558.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

real    0m48.952s
user    0m7.493s
sys     0m0.517s
```

##### Steps to reproduce

I have a set of 16296 images where the keypoints and descriptors have been detected and extracted. They are then stored on disk. I have searches running on these which are successful and I have used the Mat serialisation code over 6 million times and current search code in the same program works without error.

The java code is:

```BOWKMeansTrainer trainer = new BOWKMeansTrainer(DICTIONARY_SIZE, new TermCriteria(TermCriteria.COUNT, 100, 0.001), 1, Core.KMEANS_PP_CENTERS);
        int selector = 0;
        int descriptorCount;
        int ignoredCount = 0;
        Mat features = new Mat();
        
        
        System.out.println("  + Loading Descriptors");
        for (descriptorCount = 0; descriptorCount < trainingCount; descriptorCount++)
        {
            ObjectInputStream dataIn = new ObjectInputStream(new GZIPInputStream(new FileInputStream(Paths.get(idxDir.toString(), ids[selector] + ".sift.gz").toString()))); 

            //
            // Load keypoints and descriptors for index.
            //
            MatOfKeyPoint idxKeypoints = ImageOpenCVUtils.deSerialiseKeypointMat(dataIn);
            
            if (idxKeypoints.total() != 0)
            {
//                Mat descriptors = ImageOpenCVUtils.deSerialiseMat(dataIn);
//                features.push_back(descriptors);
                trainer.add(ImageOpenCVUtils.deSerialiseMat(dataIn));
            }
            else
            {
                // reset the descriptor count to avoid a hole.
                descriptorCount--;
                ignoredCount++;
//                System.out.println("    - Ignored - no keypoints");    
            }
            idxKeypoints.release();
            idxKeypoints = null;
            dataIn.close();
            
            
            if ((descriptorCount % 200) == 0)
            {
                System.out.printf("  + Loaded %d (%.2f%%)\n", descriptorCount, ((double)descriptorCount / (double)trainingCount) * 100.0);
                System.gc();
                System.out.println("[Used:" + ((Runtime.getRuntime().totalMemory()/1024) - (Runtime.getRuntime().freeMemory()/1024)) + "K] ["
                        + "[Free:" + (Runtime.getRuntime().freeMemory()/1024) + "K] ["
                        + "[Total:" + (Runtime.getRuntime().totalMemory()/1024) + "K]");
                System.out.flush();
            }
            
            selector += stepSelector;
            if (selector >= dbSize)
            {
                // the selector doesnt quite match the DB size. We have enough regardless.
                break;
            }
        }
        
        
        System.out.printf("  + TOTAL Training image descriptors loaded = %d (ignored %d)\n\n", descriptorCount, ignoredCount);
        
        System.out.printf("  + Dictionary size = %d\n", DICTIONARY_SIZE);
        System.out.println("  + Clustering");
        
//        Mat dictionary = trainer.cluster(features);
        Mat dictionary = trainer.cluster();
```