Haar Training: error (-215)_img.row * _img.cols == vecSize in function
Asked Answered
M

5

7

I am trying to train a Haar Cascade to detect hands. I have a vec file of size 1000. I have 40 positive images and 600 negative images. I have tried both dropping my positive images and negative images. When I run the following command I receive the following error:

opencv_traincascade -data classifier -data classifier -vec samples.vec -bg negatives.txt
-numstages 20 -minHitRate 0.999 -maxFalseAlarmRate 0.5 -numPos 1000\ -numNeg 600 -w 80
-h 40 -mode ALL -precalcValBufSize 1024\ -precalcIdxBufSize 1024

PARAMETERS:
cascadeDirName: classifier
vecFileName: samples.vec
bgFileName: negatives.txt
numPos: 1000
numNeg: 1000
numStages: 20
precalcValBufSize[Mb] : 256
precalcIdxBufSize[Mb] : 256
stageType: BOOST
featureType: HAAR
sampleWidth: 24
sampleHeight: 24
boostType: GAB
minHitRate: 0.999
maxFalseAlarmRate: 0.5
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
mode: BASIC



===== TRAINING 0-stage =====
<BEGIN
OpenCV Error: Assertion failed (_img.rows * _img.cols == vecSize) in get, file /home/lie/Desktop/Install-OpenCV-master/Ubuntu/2.4/OpenCV/opencv-2.4.9/apps/traincascade/imagestorage.cpp, line 157
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/lie/Desktop/Install-OpenCV-master/Ubuntu/2.4/OpenCV/opencv-2.4.9/apps/traincascade/imagestorage.cpp:157: error: (-215) _img.rows * _img.cols == vecSize in function get

Aborted (core dumped)

I tried lowering my positive count and doing the whole process over again and still received the same error. Any suggestions?

By the way: I am following the tutorial at : http://coding-robin.de/2013/07/22/train-your-own-opencv-haar-classifier.html

Thank you

Mclellan answered 31/12, 2014 at 22:42 Comment(8)
What's the lowest at which it still errors out?Made
I have only tried 40 and 100 positives. So I have never not gotten the error. Should I try lower than 40?Mclellan
I've had to get it down to 20 once.Made
Oh, wow. I'll try 20 and let you know. Were you receiving this error?Mclellan
I tried 20 positives and I get the same exact error. Should I keep going lower? Thanks for your help.Mclellan
Wow, weird; don't think it could help anymore. Did you try reducing your negatives?Made
Nope. I'll try that. Could it be that the negatives are too similar?Mclellan
Just dropped it to 200 negatives...same error.Mclellan
P
9

The error does not seem to be a result of large number of positive or negative samples. People do train very large data sets!

From the parameters described above, it can be noticed that the dimension of the positive samples that form the samples.vec is 24x24, which is denoted by the statement:

sampleWidth: 24
sampleHeight: 24

But while calling the opencv_traincascade function, you try to set the dimension as 80x40. Try changing this to -w 24 -h 24

Pauper answered 8/1, 2015 at 8:26 Comment(3)
After taking another look, I started to believe a similar thing was wrong. After you said it, I tried changing it to 24 and it worked. Thank you so much! Is there any reason traincascade wants 24 x 24 as default? just curious.Mclellan
I am not sure whether its a default value or not. Most probably, you will be setting these values while calling "opencv_createsamples" to create the .vec file. The positive samples will be rescaled to the width and height specified with the "opencv_createsamples" call.Pauper
Thank you. And just one more question if you don't mind. I have been told that the distortion process of opencv_createsamples is not good. I see that the alternative is to not use the distortions and create a .dat file containing a box surrounding the object of interest. Is this correct? Is there a fast way to go through every positive and note down the dimensions of this box? Thank you.Mclellan
R
1

to create the vector you said your object had w h. to train you said something else.

The parameter w h that you passed in opencv_createsamples must be the same for opencv_traincascade

see an example

from glob import glob
import os
w=108
h=45
numPos=len(glob('./positivas/*jpg'))
numNeg=len(glob("./fundo/*jpg"))
numStages=9
minHitRate=0.99

PATH_BIN="./opencv-3.4.5/build/binary/bin"

if os.path.isfile("positives.vec"):
    os.remove("positives.vec")

createsamples=f'{PATH_BIN}/opencv_createsamples ' \
              f'-bg bg.txt ' \
              f'-info info.txt ' \
              f'-num {numPos} ' \
              f'-w {w} ' \
              f'-h {h} ' \
              f'-vec positives.vec'

print(createsamples)
os.system(createsamples)

print("#############################")
print("vector criate")
print("#############################")

numPos_train=int((numPos-numNeg)/(1+(numStages-1)*(1-minHitRate)))

print("numPos ", numPos_train)

train=f'{PATH_BIN}/opencv_traincascade ' \
      f'-data data ' \
      f'-vec positives.vec ' \
      f'-bg bg.txt ' \
      f'-numPos {numPos_train} ' \
      f'-numNeg {numNeg} ' \
      f'-numStages {numStages} ' \
      f'-minHitRate {minHitRate} ' \
      f'-w {w} ' \
      f'-h {h} ' \
      f'-minhitrate 0.99 '\
      f'-maxFalseAlarmRate 0.3 ' \
      f'-precalcValBufSize 1024 ' \
      f'-precalcIdxBufSize 1024 ' \
      f'-numThreads 6'


os.system(train)
Recur answered 21/10, 2021 at 23:8 Comment(0)
C
0

I faced the same problem and specifying correct dimensions (w and h) did not work for me. It turned out that my output directory (in your case "classifier") was not empty. So the command was picking up where it left off the last time (with corresponding w and h) from the output directory. I cleared the output directory and then it worked.

Conidiophore answered 3/5, 2020 at 20:29 Comment(0)
L
-1

Lowering numPos and numNeg under the real value, works for me.

Latishalatitude answered 28/9, 2019 at 17:34 Comment(0)
S
-2

The assertion is quite clear: it expects that _img.rows*_img.cols == vecSize. I dont know what _img and vecSize are supposed to be, but that means that your input data are not correctly given. Just looking at your command line, you:

  1. Wrote -data classifier -data classifier twice. That should not be a problem but still.
  2. Wrote -numPos 1000\ -numNeg 600, while you talk about 40 positive and 600 negative images, so shouldn't you be using those figures instead?

You say you have a vecSize of size 1000. What is this vecSize for again?

Sanguinaria answered 7/1, 2015 at 9:55 Comment(2)
Well .vec or vector file is the output of a posibly well known script among haar tutorials called createsamples.pl. This pearl script uses the command opencv_createsamples. The script merges the positive and negatives to create 1000 vec samples. However through further inspection I believe vecSize is the size of a vector sample. What is strange is when I specified 80 x 40 vectors I get 320 x 160 pics . And this multiplier of 4 on each dimension occurs for all input dimensions.Mclellan
Thus _img.cols x _img.rows is not the vecSize. I assume _img is a vec sample. This is the only thing that make sense. Do u know about this script or how opencv_createsamples works? In addition i believe vectors are a required input for traincascade. Thank you for the help.Mclellan

© 2022 - 2024 — McMap. All rights reserved.