Я пишу код, в котором я читаю и изображаю и обрабатываю его и получаю Mat of double/float
, Я сохраняю его в файл, а потом читаю из этого файла.
Когда я использую double, для изображения размером 1Kx1K требуется 8 МБ, а для плавающего — 4 МБ. Поэтому я хочу использовать float
,
Вот мой код и вывод:
Mat data = readFloatFile("file_location");
cout << data.at<float>(0,0) << " " << data.at<double>(0,0);
Когда я запускаю этот код в DEBUG mode
распечатка для поплавка -0
а также двойной дает исключение, а именно assertion failed
. Но когда я использую RELEASE mode
распечатка для поплавка -0
а также 0,832 для двойного, что является истинным значением.
У меня вопрос, почему я не могу получить вывод при использовании data.at<float>(0,0)
и почему я не получаю исключение при использовании data.at<double>(0,0) in RELEASE mode
какой должен быть случай?
РЕДАКТИРОВАТЬ: Вот мой код, который пишет и читает
void writeNoiseFloat(string imageName,string fingerprintname) throw(){
Mat noise = getNoise(imageName);
FILE* fp = fopen(fingerprintname.c_str(),"wb");
if (!fp){
cout << "not found ";
perror("fopen");
}
float *buffer = new float[noise.cols];
for(int i=0;i<noise.rows;++i){
for(int j=0;j<noise.cols;++j)
buffer[j]=noise.at<float>(i,j);
fwrite(buffer,sizeof(float),noise.cols,fp);
}
fclose(fp);
free(buffer);
}
void readNoiseFloat(string fpath,Mat& data){
clock_t start = clock();
cout << fpath << endl;
FILE* fp = fopen(fpath.c_str(),"rb");
if (!fp)perror("fopen");
int size = 1024;
data.create(size,size,CV_32F);
float* buffer= new float[size];
for(int i=0;i<size;++i) {
fread(buffer,sizeof(float),size,fp);
for(int j=0;j<size;++j){
data.at<float>(i,j)=buffer[j];
cout << data.at<float>(i,j) << " " ;
cout << data.at<double>(i,j);
}
}
fclose(fp);
}
Заранее спасибо,
Прежде всего, вы не можете использовать float
а также double
в одной cv::Mat
в качестве самого хранилища используется только массив байтов. Размер этого массива будет разным для матрицы float
и матрица double
,
Итак, вы должны решить, что вы используете.
По существу, data.at<type>(x,y)
эквивалентно (type*)data_ptr[x][y]
(обратите внимание, это не точный код, его цель — показать, что происходит)
РЕДАКТИРОВАТЬ:
На основе добавленного вами кода вы создаете матрицу CV_32F
это означает, что вы должны использовать float
писать и читать и элемент. Использование двойных причин переосмысление стоимости и, безусловно, даст вам неправильный результат.
Что касается утверждения, я уверен, что внутри cv::MAT::at<class T>
есть такой код:
assert(sizeof<T>==this.getDepth());
Обычно утверждения составляются только в DEBUG
режим, поэтому вы не даете эту ошибку в RELEASE
,
EDIT2:
Не касается вопроса, но никогда не используйте free()
с new
или же delete
с malloc()
, Результатом может быть едва отлаженная проблема.
Поэтому, пожалуйста, используйте delete[]
для буфера.
Разница между отладкой & релиз:
В вашем коде есть ошибка. Это просто не отображается в режиме релиза. Для этого и нужен отладчик. Отладчик сообщает вам, если есть какие-либо ошибки / проблемы с кодом, релиз просто проходит через него …
Кроме того, компилятор оптимизирует ваш код, чтобы он работал быстрее и, следовательно, стал меньше, отладчик использует больший размер вашего HD, потому что вы можете отладить его.
Release инициализирует ваши неинициализированные переменные до 0. Это может варьироваться в зависимости от разных компиляторов.