Reading images into vec<Mat> 16bit error - c++

I'm trying to read a 3D image (stored as binary file) into a vector of Mat (so that I could read slice by slice) but always giving me segmentation error when trying to run create_mat. I'm struggling to find what went wrong. Is this the best way to read the data in the first place ?
#include <cstdint>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void read_tiff(string filename,unsigned long length,uint16_t* buffer)
{
//Reads a binary file containing little endean array of uint16_t into a single array pointed by buffer
FILE *ptr_file;
ptr_file = fopen(filename.c_str(),"rb");
rewind(ptr_file);
uint16_t temp;
unsigned int k;
for (k=0;k<length;k++)
{
fread(&temp,2,1,ptr_file);
buffer[k] = temp;
}
fclose(ptr_file);
return;
}
void create_mat(vector<Mat> dst,const int width,const int height,const int stacks,uint16_t* src)
{
int i,j,k;
int counter = 0;
for (i=0;i<stacks;i++)
{
for (j=0;j<height;j++)
{
for (k=0;k<width;k++)
{
(dst[i]).at<ushort>(j,k)= src[counter];
cout<<src[counter]<<endl;
// cout<<dst[i].at<ushort>(j,k)<<endl;
counter++;
}
}
}
}
int main()
{
string dir;
dir = "/somedir.raw";
cout<<dir<<std::endl;
unsigned long length = 1365ul*1531ul*1265ul;
uint16_t test[length];
read_tiff(dir,length,test);
int size[3] = {1265,1365,1531};
vector<Mat> img(size[0],Mat(size[1],size[2],CV_16UC1));
cout <<"image loading done"<<endl;
create_mat(img,size[1],size[2],size[0],test);
imwrite("test.jpg",img[400]);
return 0;
}

Please try this code, which fixes the 2 problems I mentioned in the comments:
Code changes are marked by CHANGED:
#include <cstdint>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void read_tiff(string filename,unsigned long length,uint16_t* buffer)
{
//Reads a binary file containing little endean array of uint16_t into a single array pointed by buffer
FILE *ptr_file;
ptr_file = fopen(filename.c_str(),"rb");
rewind(ptr_file);
uint16_t temp;
unsigned int k;
for (k=0;k<length;k++)
{
fread(&temp,2,1,ptr_file);
buffer[k] = temp;
}
fclose(ptr_file);
return;
}
void create_mat(vector<Mat> dst,const int width,const int height,const int stacks,uint16_t* src)
{
int i,j,k;
int counter = 0;
for (i=0;i<stacks;i++)
{
for (j=0;j<height;j++)
{
for (k=0;k<width;k++)
{
(dst[i]).at<ushort>(j,k)= src[counter];
cout<<src[counter]<<endl;
// cout<<dst[i].at<ushort>(j,k)<<endl;
counter++;
}
}
}
}
int main()
{
string dir;
dir = "/somedir.raw";
cout<<dir<<std::endl;
unsigned long length = 1365ul*1531ul*1265ul;
uint16_t test[length];
read_tiff(dir,length,test);
int size[3] = {1265,1365,1531};
// CHANGED: Instead of allocating Mat memory once and copy-constructing the Mat-header, create a new Mat header + memory for each vector element. Otherwise all the elements will share their pixel data (if you don't call a function that assigns new memory to the Mat)
//vector<Mat> img(size[0],Mat(size[1],size[2],CV_16UC1));
vector<Mat> img(size[0]);
for(int i=0; i<size[0]; ++i)
img[i] = Mat(size[2],size[1],CV_16UC1); // CHANGED: swapped height and width, because Mat constructor uses height-first
cout <<"image loading done"<<endl;
create_mat(img,size[1],size[2],size[0],test);
imwrite("test.jpg",img[400]);
return 0;
}

Related

StringBuilder Class in C++ not working properly

I'm working on an assignment to create a class called StringBuilder that is used for fast string concatenation. I'm supposed to store strings in a dynamic array and have methods such as Append(string) which adds a new string to the dynamic array. The method I'm currently struggling with is GetString() that creates a single string on the heap that is the length of all the strings in the dynamic array that have been added thus far.
the code I have so far is:
okay my main problem is my GetString() function prints out hello over and over again until I force quit the program in Xcode. I don't understand what inside that method is making that happen.
My header file:
#pragma once
#include <string>
using namespace std;
class StringBuilder
{
public:
StringBuilder();
//~StringBuilder();
void GetString();
void AppendAll(string*, int);
void Length();
void Clear();
void Append(string userString);
void DoubleArray(string*& allWords, int newCapacity);
private:
string* p_array;
int capacity = 5;
};
my .cpp file :
#include "StringBuilder.hpp"
#include <iostream>
#include <string>
using namespace std;
----------
void StringBuilder::Append(string userString)
{
int nextWordPosition = 0;
for(int i=0; i < capacity ; i++)
{
p_array[i] = userString;
cout << p_array[i] << endl;
nextWordPosition +=1;
if(capacity == nextWordPosition)
{
capacity *=2;
DoubleArray(p_array, capacity * 2);
}
}
nextWordPosition++;
}
void StringBuilder::DoubleArray(string*& allWords, int newCapacity)
{
string* p_temp = new string[newCapacity];
for(int i =0; i < newCapacity / 2; i++)
{
p_temp[i] = allWords[i];
}
delete[] allWords;
allWords = p_temp;
}
void StringBuilder:: GetString()
{
for(int i=0; i < capacity ; i++)
{
cout << p_array[i]<< endl;
}
}
my main.cpp file :
#include <iostream>
#include <string>
#include "StringBuilder.hpp"
using namespace std;
int main()
{
string testString = "hello";
string test = "world!";
StringBuilder Builder1;
Builder1.Append(testString);
Builder1.Append(test);
Builder1.GetString();
return 0;
}

C++ Thread: terminate called without an active exception

I'm trying to create one array of integers without repeat. To get arrays of length more than 1000, it takes a lot of time to make. So, I thought using thread would be a good decision. But I'm writing something wrong. So far following are my code:
utils.h
#ifndef UTILS_H
#define UTILS_H
typedef long long int64; typedef unsigned long long uint64;
class utils
{
public:
utils();
virtual ~utils();
static int getRandomNumberInRange(int min, int max);
static int* getRandomArray(int size, bool isRepeatAllowed);
protected:
private:
};
#endif // UTILS_H
utils.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <vector>
#include <algorithm> // for std::find
#include <sys/time.h>
#include <cctype>
#include <string>
#include <thread>
#include <vector>
#include "utils.h"
utils::utils()
{
}
utils::~utils()
{
}
int utils::getRandomNumberInRange(int min, int max)
{
if (min > max) {
int aux = min;
min = max;
max = aux;
}
else if (min == max) {
return min;
}
return (rand() % (max - min)) + min;
}
void getUniqueInteger(int* arr, int last, int* newVal)
{
int val = *newVal;
while(std::find(arr, arr+last, val) != arr+last)
{
val = utils::getRandomNumberInRange(10, 10000);
}
arr[last] = val;
}
int* utils::getRandomArray(int size, bool isRepeatAllowed)
{
int* arr = new int[size], newVal = 0;
std::vector<std::thread *> threadArr;
for (int i = 0; i < size; i++)
{
newVal = utils::getRandomNumberInRange(10, 1000);
if(!isRepeatAllowed)
{
std::thread newThread(getUniqueInteger, arr, i, &newVal);
threadArr.push_back( &newThread);
}
else
{
arr[i] = newVal;
}
}
int spawnedThreadCount = threadArr.size();
if (spawnedThreadCount > 0)
{
for (int j = 0; j < spawnedThreadCount; j++)
{
threadArr[j]->join();
//delete threadArr[j];
}
}
return arr;
}
And calling this in:
main.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include "utils.h"
using namespace std;
int main(int argc, char *argv[])
{
if (argc != 2 && utils::isInteger(argv[1]))
{
cout << "You have to provide an integer input to this program!!!" << endl;
return 0;
}
int size = stoi( argv[1] );
srand(time(NULL));
int* arr = utils::getRandomArray(size, false);
return 0;
}
Compiling by: g++ -Wall -g -std=c++11 -pthread -o a.out ./utils.cpp ./main.cpp
But, whenever I'm running the program by ./a.out 10, it's terminating by giving the output:
terminate called without an active exception
Aborted (core dumped)
Please help. Thanks in advance.
Your code that creates the thread creates a stack variable that is immediately destroyed. You need to change this:
if(!isRepeatAllowed)
{
std::thread newThread(getUniqueInteger, arr, i, &newVal);
threadArr.push_back( &newThread);
}
to this:
if(!isRepeatAllowed)
{
std::thread* newThread = new std::thread(getUniqueInteger, arr, i, &newVal);
threadArr.push_back( newThread);
}
Then uncomment your delete line later on.
You create your thread inside the if statement. Then you push a pointer to it by getting a reference. This pointer will not keep the thread object alive, rather when the if is exited your object's destructor is called.
This means that std::terminate is called to terminate the running thread and you're left with a dangling pointer.

c++ 2d array maze navigation

I'm new to c++ and wondering if I'm doing this the best way. I need to read in a line from a text file and build an array from it and then navigate it. Let me know if I'm doing something wrong. Can I access matrix the way I am?
header:
#ifndef MAZE_HPP_
#define MAZE_HPP_
#include <fstream>
#include <vector>
#include <string>
class Maze
{
public:
Maze(int size);
~Maze() {}
enum Direction { DOWN, RIGHT, UP, LEFT };
// Implement the following functions:
// read maze from file, find starting location
void readFromFile(std::ifstream &f);
// make a single step advancing toward the exit
void step();
// return true if the maze exit has been reached, false otherwise
bool atExit();
// set row and col to current position of 'x'
void getCurrentPosition(int &row, int &col);
// You can add more functions if you like
private:
// Private data and methods
int size;
static string matrix[30][30];
};
#endif /* MAZE_HPP_ */
c++ file:
#include <iostream>
#include "maze.hpp"
#include "utils.hpp"
#include <vector>
#include <string>
Maze::Maze(int size) {
size = size;
}
Maze::void readFromeFile(std::ifstream &f) {
std::string line;
int i, j;
while(std::getline(f, line)) {
for(i = 0; i < line.length(); i++) {
for(j = 0; j < line.length(); j++) {
matrix[i][j] = line.at(j);
}
}
}
}
Maze::void step() {
}
Maze::bool atExit() {
}
Maze::void getCurrentPosition(int &row, int &col) {
}
Maze::void readFromeFile {}
Maze::void step() {}
Maze::bool atExit() {}
Maze::void getCurrentPosition(int &row, int &col) {}
these should be
void Maze::readFromeFile{}
void Maze::step() {}
bool Maze::atExit(){}
void Maze::getCurrentPosition(int &row, int &col){}

C++ VALGRIND Uninitialised value was created by a heap allocation

I have a problem. When I compile the program I don't have any errors, but when I use valgrind:
Uninitialized value was created by a heap allocation (line with new)
Conditional jump or move depends on uninitialized value(s)(line with delete)
I search through the forums however I didn't find much information which could help me.
I would be really grateful for a hint.
My program
#include <cstdlib>
#include <stdint.h>
#include <cstdio>
#include <iostream>
#include <string>
#include <istream>
#include <cstring>
#include <fstream>
#include <sstream>
#include <cctype>
using namespace std;
using std::cout;
using std::endl;
int dlugosc,miejsce;
ifstream file;
class channel
{
public:
int start;
double length;
int bytespix;
int resolution;
channel(double g) : start(g),
length(0),
bytespix(0),
resolution(0)
{
}
};
int fileopen() // opens the file and returns its size
{
file.open ("0_dlc.000", ios::in|ios::binary);
if( file.good() == true )
{
cout << "Uzyskano dostep do pliku!" << endl;
}
else
{
cout<< "File cannot open" <<endl;
}
file.seekg(0, file.end);
dlugosc = file.tellg();
return dlugosc;
}
int findword(const char* slowo,int startplace)
{
int m;
int c=0;
int cur=0;
unsigned int equal=0;
char element=0;
file.seekg (startplace, file.beg);
for(m=0;m<dlugosc;m++)
{
file.get(element);
if(element==slowo[cur])
{
equal++;
cur++;
}
else
{
equal=0;
cur=0;
if(element==slowo[cur])
{
equal++;
cur++;
}
}
if(equal==strlen(slowo))
{
return m+startplace;
}
}
return 0;
}
int findvalue(const char* wartosc,int startpoint)
{
int p;
int g;
char element=0;
char* buffer = new char[9];
miejsce = findword(wartosc,startpoint); // miejsce to global variable
file.seekg (miejsce+1, file.beg);
for(p=0;(int)element<58;p++)
{
file.get(element);
if((int)element>58 || (int)element<48)
break;
else
buffer[p] = element;
}
buffer[p]='\0';
g = atoi(buffer);
delete [] buffer;
return g;
}
int main()
{
int a,h=0,channels,start=0,length=0,resolution=0,bytespix=0,m=0;
const char* slowko="Data offset: ";
dlugosc=fileopen();
channel** kanaly=0;
kanaly = new channel*[9];
miejsce=0;
for(a=0;a<9;a++)
{
kanaly[a] = new channel(4);
start = findvalue("Data offset: ",miejsce+20);
kanaly[a]->start=start;
}
for(m=0;m<9;m++)
{
delete kanaly[m];
}
delete []kanaly;
file.close();
}
The problem is in the constructor of channel. Initialize all member variables, and the problem will go away :
class channel
{
public:
double start;
double length;
int bytespix;
int resolution;
channel(double g) : start(g),
length(0),
bytespix(0),
resolution(0)
{
}
};

c++ vector causes array subscript error. Debugger shows error CXX0004

I am implementing a floyd-warshall algorithm in MS VS 2010. I am using the vector container. These seemingly innocent lines:
#include <iostream>
#include <iomanip>
#include <vector>
#include <fstream>
#include <string>
#include <limits>
using namespace std;
const double inf = numeric_limits<double>::infinity();
struct node{
int value;
//path not used here
//node *predecessor;
};
struct edge{
int source;
int target;
double weight;
};
vector<edge> EDGES;
cause a problem visible at the debugger when I stop at a breakpoint at the very start of main() body: Instead of having EDGES as the beautiful menu it should, I get a red exclamination mark at the name, and CXX0004: Error: Syntax error. Trying to run the program causes debug assertion: vector subscript out of range. The exact same lines work fine in a similar program I've made. What's wrong?
Here is the whole code:
#include <iostream>
#include <iomanip>
#include <vector>
#include <fstream>
#include <string>
#include <limits>
using namespace std;
const double inf = numeric_limits<double>::infinity();
struct node{
int value;
//path not used here
//node *predecessor;
};
struct edge{
int source;
int target;
double weight;
};
vector<edge> EDGES;
vector<node> V;
vector< vector< vector< double > > > R;
int u;//source
unsigned Ecount,Vcount;
void insert_from_keyboard(void)
{
unsigned i,j;
cout<<"Keyboard insertion selected. Enter vertex count: ";
cin>>Vcount;
V.resize(Vcount);
for(i=0;i<Vcount;i++)
V[i].value=i+1;//naming nodes, start from 1
R.resize(Vcount+1);
for(i=0;i<Vcount+1;i++)
{
R[i].resize(Vcount);
for(j=0;j<Vcount;j++)
R[i][j].resize(Vcount,inf);
}
cout<<"Nodes 1 to "<<Vcount<<" created.\nEnter edge count: ";
cin>>Ecount;
EDGES.resize(Ecount);
cout<<"Enter "<<Ecount<<" triplets representing directed edges (source, target, weight): ";
for(i=0;i<Ecount;i++)
cin>>EDGES[i].source>>EDGES[i].target>>EDGES[i].weight;
return;
}
bool floyd_warshall(void)
{
unsigned i,j,k;
for(i=0;i<Vcount;i++)
R[0][i][i] = 0;
for(i=0;i<Ecount;i++)
R[0][EDGES[i].source-1][EDGES[i].target-1] = EDGES[i].weight;
for(i=1;i<Vcount+1;i++)
for(j=0;j<Vcount;j++)
for(k=0;k<Vcount;k++)
R[i][j][k]= R[i-1][j][k] > R[i-1][j][i] + R[i-1][i][k] ? R[i-1][j][i] + R[i-1][i][k] : R[i-1][j][k];
for(i=0;i<Vcount;i++)
for(j=0;j<Vcount;j++)
if ( R[i][j][j]<0 )
return false;
return true;
}
void printR()
{
//printing routine, should not bother....
//the log function is used to calculate maximum length of numbers, used for formatting...
unsigned l,i,j, wl=5, wd=8;//width for printing whitespacEDGES l for L(...), d for data
for(l=0;l<Vcount+1;l++)
{
cout<<"R("<<setw(wl)<<l+1<<"):\n\n";
for(i=0;i<Vcount;i++)
{
cout<<setw(5+wl+wd/2)<<R[l][i][0];
for(j=1;j<Vcount;j++)
cout<<setw(wd)<<R[l][i][j];
cout<<endl;
}
cout<<"\n\n";
}
}
void insert_from_file(string filename)
{
unsigned i,j;
ifstream f (filename.c_str());
f>>Vcount>>Ecount;
V.resize(Vcount);
for(i=0;i<Vcount;i++)
V[i].value=i+1;//naming nodes, start from 1
R.resize(Vcount+1);
for(i=0;i<Vcount+1;i++)
{
R[i].resize(Vcount);
for(j=0;j<Vcount;j++)
R[i][j].resize(Vcount,inf);
}
EDGES.resize(Ecount);
for(i=0;i<Ecount;i++)
f>>EDGES[i].source>>EDGES[i].target>>EDGES[i].weight;
f.close();
cout<<"Insert from file "<<filename<<" successful\n\n";
}
int main(void)
{
//insert_from_keyboard();
insert_from_file("A22.txt");
bool result =floyd_warshall();
printR();
cout<<"Result of algorithm: "<<(result ? "TRUE, no negative" : "FALSE, negative" )<<" cycles encountered.\n";
system("PAUSE");
return 0;
}