Opencv 2 multi-threshold Otsu method [duplicate] - c++

I'm trying to implement multi-level Otsu's thresholding, more specifically I need 3 thresholds/4 classes.
I'm aware of 2 similair questions on SO about it: #34856019 and #22706742.
The problem is that I don't get good results: I've read several articles with sample images and thresholds found by that code differ from the ones in these papers.
Let's say I have a picture with 3 circles on the black background, the brightness of the circles differ from very bright to dark:
Sample Image
Am I right to suppose to get as a result 4 classes: black background and 3 more classes according to circles' intensity?
My program gives me these threshold values: 226, 178, 68
As a result, the third circle is completely invisible - it's in the same class as the background.
Can someone please check these values and/or the source code? Maybe it is possible to check this image using Matlab or somehow else...
By the way, what's the best way to handle divisions by zero, which happen often with zero values in histogram?
The source code:
void MultilevelThresholding(cv::Mat& src)
{
int histogram[256] = { 0 };
int pixelsCount = src.cols * src.rows;
for (int y = 0; y < src.rows; y++)
{
for (int x = 0; x < src.cols; x++)
{
uchar value = src.at<uchar>(y, x);
histogram[value]++;
}
}
double c = 0;
double Mt = 0;
double p[256] = { 0 };
for (int i = 0; i < 256; i++)
{
p[i] = (double) histogram[i] / (double) pixelsCount;
Mt += i * p[i];
}
int optimalTreshold1 = 0;
int optimalTreshold2 = 0;
int optimalTreshold3 = 0;
double maxBetweenVar = 0;
double w0 = 0;
double m0 = 0;
double c0 = 0;
double p0 = 0;
double w1 = 0;
double m1 = 0;
double c1 = 0;
double p1 = 0;
double w2 = 0;
double m2 = 0;
double c2 = 0;
double p2 = 0;
for (int tr1 = 0; tr1 < 256; tr1++)
{
p0 += p[tr1];
w0 += (tr1 * p[tr1]);
if (p0 != 0)
{
m0 = w0 / p0;
}
c0 = p0 * (m0 - Mt) * (m0 - Mt);
c1 = 0;
w1 = 0;
m1 = 0;
p1 = 0;
for (int tr2 = tr1 + 1; tr2 < 256; tr2++)
{
p1 += p[tr2];
w1 += (tr2 * p[tr2]);
if (p1 != 0)
{
m1 = w1 / p1;
}
c1 = p1 * (m1 - Mt) * (m1 - Mt);
c2 = 0;
w2 = 0;
m2 = 0;
p2 = 0;
for (int tr3 = tr2 + 1; tr3 < 256; tr3++)
{
p2 += p[tr3];
w2 += (tr3 * p[tr3]);
if (p2 != 0)
{
m2 = w2 / p2;
}
c2 = p2 * (m2 - Mt) * (m2 - Mt);
c = c0 + c1 + c2;
if (maxBetweenVar < c)
{
maxBetweenVar = c;
optimalTreshold1 = tr1;
optimalTreshold2 = tr2;
optimalTreshold3 = tr3;
}
}
}
}

So, I've figured it out. The final source code for 4 classes (3 thresholds) Otsu thresholding:
// cv::Mat& src - source image's matrix
int histogram[256] = { 0 };
int pixelsCount = src.cols * src.rows;
for (int y = 0; y < src.rows; y++)
{
for (int x = 0; x < src.cols; x++)
{
uchar value = src.at<uchar>(y, x);
histogram[value]++;
}
}
double c = 0;
double Mt = 0;
double p[256] = { 0 };
for (int i = 0; i < 256; i++)
{
p[i] = (double) histogram[i] / (double) pixelsCount;
Mt += i * p[i];
}
int optimalTreshold1 = 0;
int optimalTreshold2 = 0;
int optimalTreshold3 = 0;
double maxBetweenVar = 0;
double w0 = 0;
double m0 = 0;
double c0 = 0;
double p0 = 0;
double w1 = 0;
double m1 = 0;
double c1 = 0;
double p1 = 0;
double w2 = 0;
double m2 = 0;
double c2 = 0;
double p2 = 0;
for (int tr1 = 0; tr1 < 256; tr1++)
{
p0 += p[tr1];
w0 += (tr1 * p[tr1]);
if (p0 != 0)
{
m0 = w0 / p0;
}
c0 = p0 * (m0 - Mt) * (m0 - Mt);
c1 = 0;
w1 = 0;
m1 = 0;
p1 = 0;
for (int tr2 = tr1 + 1; tr2 < 256; tr2++)
{
p1 += p[tr2];
w1 += (tr2 * p[tr2]);
if (p1 != 0)
{
m1 = w1 / p1;
}
c1 = p1 * (m1 - Mt) * (m1 - Mt);
c2 = 0;
w2 = 0;
m2 = 0;
p2 = 0;
for (int tr3 = tr2 + 1; tr3 < 256; tr3++)
{
p2 += p[tr3];
w2 += (tr3 * p[tr3]);
if (p2 != 0)
{
m2 = w2 / p2;
}
c2 = p2 * (m2 - Mt) * (m2 - Mt);
double p3 = 1 - (p0 + p1 + p2);
double w3 = Mt - (w0 + w1 + w2);
double m3 = w3 / p3;
double c3 = p3 * (m3 - Mt) * (m3 - Mt);
double c = c0 + c1 + c2 + c3;
if (maxBetweenVar < c)
{
maxBetweenVar = c;
optimalTreshold1 = tr1;
optimalTreshold2 = tr2;
optimalTreshold3 = tr3;
}
}
}
}
Source image
Result: 3 thresholds / 4 classes
threshold values: 179, 92, 25

Related

C++ neural network implemented from scratch cannot get above 50% on MNIST

So I have implemented a fully connected one hidden layer neural network in C++ using Eigen for matrix multiplication. It uses minibatch gradient descent.
However, my model cannot get above 50% accuracy on mnist. I have tried learning rates from between 0.0001 and 10. The model does overfit on training sizes < 100 (with ~90% accuracy which is still pretty bad), albeit extremely slowly.
What might be causing this low accuracy and extremely slow learning? My main concern is that the backpropagation is incorrect. Furthermore, I would prefer not to add any other optimization techniques (learning rate schedule, regularization, etc.).
Feed forward and backprop code:
z1 = (w1 * mbX).colwise() + b1;
a1 = sigmoid(z1);
z2 = (w2 * a1).colwise() + b2;
a2 = sigmoid(z2);
MatrixXd err = ((double) epsilon)/((double) minibatch_size) * ((a2 - mbY).array() * sigmoid_derivative(z2).array()).matrix();
b2 = b2 - err * ones;
w2 = w2 - (err * a1.transpose());
err = ((w2.transpose() * err).array() * sigmoid_derivative(z1).array()).matrix();
b1 = b1 - err * ones;
w1 = w1 - (err * mbX.transpose());
Full program code:
#include <iostream>
#include <fstream>
#include <math.h>
#include <cstdlib>
#include <Eigen/Dense>
#include <vector>
#include <string>
using namespace Eigen;
#define N 30
#define epsilon 0.7
#define epoch 1000
//sizes
const int minibatch_size = 10;
const int training_size = 10000;
const int val_size = 10;
unsigned int num, magic, rows, cols;
//images
unsigned int image[training_size][28][28];
unsigned int val_image[val_size][28][28];
//labels
unsigned int label[training_size];
unsigned int val_label[val_size];
//inputs
MatrixXd X(784, training_size);
MatrixXd Y = MatrixXd::Zero(10, training_size);
//minibatch
MatrixXd mbX(784, minibatch_size);
MatrixXd mbY = MatrixXd::Zero(10, minibatch_size);
//validation
MatrixXd Xv(784, val_size);
MatrixXd Yv = MatrixXd::Zero(10, val_size);
//Image processing courtesy of https://stackoverflow.com/users/11146076/%e5%bc%a0%e4%ba%91%e9%93%ad
unsigned int in(std::ifstream& icin, unsigned int size) {
unsigned int ans = 0;
for (int i = 0; i < size; i++) {
unsigned char x;
icin.read((char*)&x, 1);
unsigned int temp = x;
ans <<= 8;
ans += temp;
}
return ans;
}
void input(std::string ipath, std::string lpath, std::string ipath2, std::string lpath2) {
std::ifstream icin;
//training data
icin.open(ipath, std::ios::binary);
magic = in(icin, 4), num = in(icin, 4), rows = in(icin, 4), cols = in(icin, 4);
for (int i = 0; i < training_size; i++) {
int val = 0;
for (int x = 0; x < rows; x++) {
for (int y = 0; y < cols; y++) {
image[i][x][y] = in(icin, 1);
X(val, i) = image[i][x][y]/255;
val++;
}
}
}
icin.close();
//training labels
icin.open(lpath, std::ios::binary);
magic = in(icin, 4), num = in(icin, 4);
for (int i = 0; i < training_size; i++) {
label[i] = in(icin, 1);
Y(label[i], i) = 1;
}
icin.close();
//validation data
icin.open(ipath2, std::ios::binary);
magic = in(icin, 4), num = in(icin, 4), rows = in(icin, 4), cols = in(icin, 4);
for (int i = 0; i < val_size; i++) {
int val = 0;
for (int x = 0; x < rows; x++) {
for (int y = 0; y < cols; y++) {
val_image[i][x][y] = in(icin, 1);
Xv(val, i) = val_image[i][x][y]/255;
val++;
}
}
}
icin.close();
//validation labels
icin.open(lpath2, std::ios::binary);
magic = in(icin, 4), num = in(icin, 4);
for (int i = 0; i < val_size; i++) {
val_label[i] = in(icin, 1);
Yv(val_label[i], i) = 1;
}
icin.close();
}
//Neural Network calculations
MatrixXd sigmoid(MatrixXd m) {
m *= -1;
return (1/(1 + m.array().exp())).matrix();
}
MatrixXd sigmoid_derivative(MatrixXd m) {
return (sigmoid(m).array() * (1 - sigmoid(m).array())).matrix();
}
//Initialize weights and biases
//hidden layer
VectorXd b1 = MatrixXd::Zero(N, 1);
MatrixXd w1 = MatrixXd::Random(N, 784);
//output
VectorXd b2 = MatrixXd::Zero(10, 1);
MatrixXd w2 = MatrixXd::Random(10, N);
//Initialize intermediate values
MatrixXd z1, z2, a1, a2, z1v, z2v, a1v, a2v;
MatrixXd ones = MatrixXd::Constant(minibatch_size, 1, 1);
int main() {
input("C:\\Users\\Aaron\\Documents\\Test\\train-images-idx3-ubyte\\train-images.idx3-ubyte", "C:\\Users\\Aaron\\Documents\\Test\\train-labels-idx1-ubyte\\train-labels.idx1-ubyte", "C:\\Users\\Aaron\\Documents\\Test\\t10k-images-idx3-ubyte\\t10k-images.idx3-ubyte", "C:\\Users\\Aaron\\Documents\\Test\\t10k-labels-idx1-ubyte\\t10k-labels.idx1-ubyte");
std::cout << "Finished Image Processing" << std::endl;
//std::cout << w1 << std::endl;
std::vector<double> val_ac;
std::vector<double> c;
std::vector<int> order;
for (int i = 0; i < training_size; i++) {
order.push_back(i);
}
for (int i = 0; i < epoch; i++) {
//feed forward
std::random_shuffle(order.begin(), order.end());
for (int j = 0; j < training_size/minibatch_size; j++) {
for (int k = 0; k < minibatch_size; k++) {
int index = order[j * minibatch_size + k];
mbX.col(k) = X.col(index);
mbY.col(k) = Y.col(index);
}
z1 = (w1 * mbX).colwise() + b1;
a1 = sigmoid(z1);
z2 = (w2 * a1).colwise() + b2;
a2 = sigmoid(z2);
MatrixXd err = ((double) epsilon)/((double) minibatch_size) * ((a2 - mbY).array() * sigmoid_derivative(z2).array()).matrix();
//std::cout << err << std::endl;
b2 = b2 - err * ones;
w2 = w2 - (err * a1.transpose());
err = ((w2.transpose() * err).array() * sigmoid_derivative(z1).array()).matrix();
//std::cout << err << std::endl;
b1 = b1 - err * ones;
w1 = w1 - (err * mbX.transpose());
}
//validation
z1 = (w1 * X).colwise() + b1;
a1 = sigmoid(z1);
z2 = (w2 * a1).colwise() + b2;
a2 = sigmoid(z2);
double cost = 1/((double) training_size) * ((a2 - Y).array() * (a2 - Y).array()).matrix().sum();
c.push_back(cost);
int correct = 0;
for (int i = 0; i < training_size; i++) {
double maxP = -1;
int na;
for (int j = 0; j < 10; j++) {
if (a2(j, i) > maxP) {
maxP = a2(j, i);
na = j;
}
}
if (na == label[i]) correct++;
}
val_ac.push_back(((double) correct) / ((double) training_size));
std::cout << "Finished Epoch " << i + 1 << std::endl;
std::cout << "Cost: " << cost << std::endl;
std::cout << "Accuracy: " << ((double) correct) / ((double) training_size) << std::endl;
}
//plot accuracy
FILE * gp = _popen("gnuplot", "w");
fprintf(gp, "set terminal wxt size 600,400 \n");
fprintf(gp, "set grid \n");
fprintf(gp, "set title '%s' \n", "NN");
fprintf(gp, "plot '-' w line, '-' w lines \n");
for (int i = 0; i < epoch; i++) {
fprintf(gp, "%f %f \n", i + 1.0, c[i]);
}
fprintf(gp, "e\n");
//validation accuracy
for (int i = 0; i < epoch; i++) {
fprintf(gp, "%f %f \n", i + 1.0, val_ac[i]);
}
fprintf(gp, "e\n");
fflush(gp);
system("pause");
_pclose(gp);
return 0;
}
UPD
Here is a graph of the accuracy on the training dataset (green) and the loss (purple)
https://i.stack.imgur.com/Ya2yR.png
Here is a graph of the loss for the training data and validation data:
https://imgur.com/a/4gmFCrk
The loss of the validation data is increasing past a certain point, which shows signs of overfitting. However, the accuracy still remains abysmal even on the training data.
unsigned int val_image[val_size][28][28];
Xv(val, i) = val_image[i][x][y]/255;
Can you try again with Xv(val, i) = val_image[i][x][y] / 255.0;
There too:
X(val, i) = image[i][x][y]/255;
With the code as written, Xv is 0 very often, and 1, when the image as value 255. With a floating point division, you'll get value between 0.0 and 1.0.
You'll need to check your code for other places where you may be dividing integers.
N.b.: In C++, 240/255 is 0.

How to to find smallest (optimized) distance between two vectors in C++

I'm translating Python's version of 'page_dewarper' (https://mzucker.github.io/2016/08/15/page-dewarping.html) into C++. I'm going to use dlib, which is a fantastic tool, that helped me in a few optimization problems before. In line 748 of Github repo (https://github.com/mzucker/page_dewarp/blob/master/page_dewarp.py) Matt uses optimize function from Scipy, to find the minimal distance between two vectors. I think, my C++ equivalent should be solve_least_squares_lm() or solve_least_squares(). I'll give a concrete example to analyze.
My data:
a) dstpoints is a vector with OpenCV points - std::vector<cv::Point2f> (I have 162 points in this example, they are not changing),
b) ppts is also std::vector<cv::Point2f> and the same size as dstpoints.
std::vector<cv::Point2f> ppts = project_keypoints(params, input);
It is dependent on:
- dlib::column_vector 'input' is 2*162=324 long and is not changing,
- dlib::column_vector 'params' is 189 long and its values should be changed to get the minimal value of variable 'suma', something like this:
double suma = 0.0;
for (int i=0; i<dstpoints_size; i++)
{
suma += pow(dstpoints[i].x - ppts[i].x, 2);
suma += pow(dstpoints[i].y - ppts[i].y, 2);
}
I'm looking for 'params' vector that will give me the smallest value of 'suma' variable. Least squares algorithm seems to be a good option to solve it: http://dlib.net/dlib/optimization/optimization_least_squares_abstract.h.html#solve_least_squares, but I don't know if it is good for my case.
I think, my problem is that for every different 'params' vector I get different 'ppts' vector, not only single value, and I don't know if solve_least_squares function can match my example.
I must calculate residual for every point. I think, my 'list' from aforementioned link should be something like this:
(ppts[i].x - dstpoints[i].x, ppts[i].y - dstpoints[i].y, ppts[i+1].x - dstpoints[i+1].x, ppts[i+1].y - dstpoints[i+1].y, etc.)
, where 'ppts' vector depends on 'params' vector and then this problem can be solved with least squares algorithm. I don't know how to create data_samples with these assumptions, because it requires dlib::input_vector for every sample, as it is shown in example: http://dlib.net/least_squares_ex.cpp.html.
Am I thinking right?
I'm doing the same thing this days. My solution is writing a Powell Class by myself. It works, but really slowly. The program takes 2 minutes in dewarping linguistics_thesis.jpg.
I don't know what cause the program running so slowly. Maybe because of the algorithm or the code has some extra loop. I'm a Chinese student and my school only have java lessons. So it is normal if you find some extra codes in my codes.
Here is my Powell class.
using namespace std;
using namespace cv;
class MyPowell
{
public:
vector<vector<double>> xi;
vector<double> pcom;
vector<double> xicom;
vector<Point2d> dstpoints;
vector<double> myparams;
vector<double> params;
vector<Point> keypoint_index;
Point2d dst_br;
Point2d dims;
int N;
int itmax;
int ncom;
int iter;
double fret, ftol;
int usingAorB;
MyPowell(vector<Point2d> &dstpoints, vector<double> &params, vector<Point> &keypoint_index);
MyPowell(Point2d &dst_br, vector<double> &params, Point2d & dims);
MyPowell();
double obj(vector<double> &params);
void powell(vector<double> &p, vector<vector<double>> &xi, double ftol, double &fret);
double sign(double a);// , double b);
double sqr(double a);
void linmin(vector<double> &p, vector<double> &xit, int n, double &fret);
void mnbrak(double & ax, double & bx, double & cx,
double & fa, double & fb, double & fc);
double f1dim(double x);
double brent(double ax, double bx, double cx, double & xmin, double tol);
vector<double> usePowell();
void erase(vector<double>& pbar, vector<double> &prr, vector<double> &pr);
};
#include"Powell.h"
MyPowell::MyPowell(vector<Point2d> &dstpoints, vector<double>& params, vector<Point> &keypoint_index)
{
this->dstpoints = dstpoints;
this->myparams = params;
this->keypoint_index = keypoint_index;
N = params.size();
itmax = N * N;
usingAorB = 1;
}
MyPowell::MyPowell(Point2d & dst_br, vector<double>& params, Point2d & dims)
{
this->dst_br = dst_br;
this->myparams.push_back(dims.x);
this->myparams.push_back(dims.y);
this->params = params;
this->dims = dims;
N = 2;
itmax = N * 1000;
usingAorB = 2;
}
MyPowell::MyPowell()
{
usingAorB = 3;
}
double MyPowell::obj(vector<double> &myparams)
{
if (1 == usingAorB)
{
vector<Point2d> ppts = Dewarp::projectKeypoints(keypoint_index, myparams);
double total = 0;
for (int i = 0; i < ppts.size(); i++)
{
double x = dstpoints[i].x - ppts[i].x;
double y = dstpoints[i].y - ppts[i].y;
total += (x * x + y * y);
}
return total;
}
else if(2 == usingAorB)
{
dims.x = myparams[0];
dims.y = myparams[1];
//cout << "dims.x " << dims.x << " dims.y " << dims.y << endl;
vector<Point2d> vdims = { dims };
vector<Point2d> proj_br = Dewarp::projectXY(vdims, params);
double total = 0;
double x = dst_br.x - proj_br[0].x;
double y = dst_br.y - proj_br[0].y;
total += (x * x + y * y);
return total;
}
return 0;
}
void MyPowell::powell(vector<double> &x, vector<vector<double>> &direc, double ftol, double &fval)
{
vector<double> x1;
vector<double> x2;
vector<double> direc1;
int myitmax = 20;
if(N>500)
myitmax = 10;
else if (N > 300)
{
myitmax = 15;
}
double fx2, t, fx, dum, delta;
fval = obj(x);
int bigind;
for (int j = 0; j < N; j++)
{
x1.push_back(x[j]);
}
int iter = 0;
while (true)
{
do
{
do
{
iter += 1;
fx = fval;
bigind = 0;
delta = 0.0;
for (int i = 0; i < N; i++)
{
direc1 = direc[i];
fx2 = fval;
linmin(x, direc1, N, fval);
if (fabs(fx2 - fval) > delta)
{
delta = fabs(fx2 - fval);
bigind = i;
}
}
if (2.0 * fabs(fx - fval) <= ftol * (fabs(fx) + fabs(fval)) + 1e-7)
{
erase(direc1, x2, x1);
return;
}
if (iter >= itmax)
{
cout << "powell exceeding maximum iterations" << endl;
return;
}
if (!x2.empty())
{
x2.clear();
}
for (int j = 0; j < N; j++)
{
x2.push_back(2.0*x[j] - x1[j]);
direc1[j] = x[j] - x1[j];
x1[j] = x[j];
}
myitmax--;
cout << fx2 << endl;
fx2 = obj(x2);
if (myitmax < 0)
return;
} while (fx2 >= fx);
dum = fx - 2 * fval + fx2;
t = 2.0*dum*pow((fx - fval - delta), 2) - delta * pow((fx - fx2), 2);
} while (t >= 0.0);
linmin(x, direc1, N, fval);
direc[bigind] = direc1;
}
}
double MyPowell::sign(double a)//, double b)
{
if (a > 0.0)
{
return 1;
}
else
{
if (a < 0.0)
{
return -1;
}
}
return 0;
}
double MyPowell::sqr(double a)
{
return a * a;
}
void MyPowell::linmin(vector<double>& p, vector<double>& xit, int n, double &fret)
{
double tol = 1e-2;
ncom = n;
pcom = p;
xicom = xit;
double ax = 0.0;
double xx = 1.0;
double bx = 0.0;
double fa, fb, fx, xmin;
mnbrak(ax, xx, bx, fa, fx, fb);
fret = brent(ax, xx, bx, xmin, tol);
for (int i = 0; i < n; i++)
{
xit[i] = (xmin * xit[i]);
p[i] += xit[i];
}
}
void MyPowell::mnbrak(double & ax, double & bx, double & cx,
double & fa, double & fb, double & fc)
{
const double GOLD = 1.618034, GLIMIT = 110.0, TINY = 1e-20;
double val, fw, tmp2, tmp1, w, wlim;
double denom;
fa = f1dim(ax);
fb = f1dim(bx);
if (fb > fa)
{
val = ax;
ax = bx;
bx = val;
val = fb;
fb = fa;
fa = val;
}
cx = bx + GOLD * (bx - ax);
fc = f1dim(cx);
int iter = 0;
while (fb >= fc)
{
tmp1 = (bx - ax) * (fb - fc);
tmp2 = (bx - cx) * (fb - fa);
val = tmp2 - tmp1;
if (fabs(val) < TINY)
{
denom = 2.0*TINY;
}
else
{
denom = 2.0*val;
}
w = bx - ((bx - cx)*tmp2 - (bx - ax)*tmp1) / (denom);
wlim = bx + GLIMIT * (cx - bx);
if ((bx - w) * (w - cx) > 0.0)
{
fw = f1dim(w);
if (fw < fc)
{
ax = bx;
fa = fb;
bx = w;
fb = fw;
return;
}
else if (fw > fb)
{
cx = w;
fc = fw;
return;
}
w = cx + GOLD * (cx - bx);
fw = f1dim(w);
}
else
{
if ((cx - w)*(w - wlim) >= 0.0)
{
fw = f1dim(w);
if (fw < fc)
{
bx = cx;
cx = w;
w = cx + GOLD * (cx - bx);
fb = fc;
fc = fw;
fw = f1dim(w);
}
}
else if ((w - wlim)*(wlim - cx) >= 0.0)
{
w = wlim;
fw = f1dim(w);
}
else
{
w = cx + GOLD * (cx - bx);
fw = f1dim(w);
}
}
ax = bx;
bx = cx;
cx = w;
fa = fb;
fb = fc;
fc = fw;
}
}
double MyPowell::f1dim(double x)
{
vector<double> xt;
for (int j = 0; j < ncom; j++)
{
xt.push_back(pcom[j] + x * xicom[j]);
}
return obj(xt);
}
double MyPowell::brent(double ax, double bx, double cx, double & xmin, double tol = 1.48e-8)
{
const double CGOLD = 0.3819660, ZEPS = 1.0e-4;
int itmax = 500;
double a = MIN(ax, cx);
double b = MAX(ax, cx);
double v = bx;
double w = v, x = v;
double deltax = 0.0;
double fx = f1dim(x);
double fv = fx;
double fw = fx;
double rat = 0, u = 0, fu;
int iter;
int done;
double dx_temp, xmid, tol1, tol2, tmp1, tmp2, p;
for (iter = 0; iter < 500; iter++)
{
xmid = 0.5 * (a + b);
tol1 = tol * fabs(x) + ZEPS;
tol2 = 2.0*tol1;
if (fabs(x - xmid) <= (tol2 - 0.5*(b - a)))
break;
done = -1;
if (fabs(deltax) > tol1)
{
tmp1 = (x - w) * (fx - fv);
tmp2 = (x - v) * (fx - fw);
p = (x - v) * tmp2 - (x - w) * tmp1;
tmp2 = 2.0 * (tmp2 - tmp1);
if (tmp2 > 0.0)
p = -p;
tmp2 = fabs(tmp2);
dx_temp = deltax;
deltax = rat;
if ((p > tmp2 * (a - x)) && (p < tmp2 * (b - x)) &&
fabs(p) < fabs(0.5 * tmp2 * dx_temp))
{
rat = p / tmp2;
u = x + rat;
if ((u - a) < tol2 || (b - u) < tol2)
{
rat = fabs(tol1) * sign(xmid - x);
}
done = 0;
}
}
if(done)
{
if (x >= xmid)
{
deltax = a - x;
}
else
{
deltax = b - x;
}
rat = CGOLD * deltax;
}
if (fabs(rat) >= tol1)
{
u = x + rat;
}
else
{
u = x + fabs(tol1) * sign(rat);
}
fu = f1dim(u);
if (fu > fx)
{
if (u < x)
{
a = u;
}
else
{
b = u;
}
if (fu <= fw || w == x)
{
v = w;
w = u;
fv = fw;
fw = fu;
}
else if (fu <= fv || v == x || v == w)
{
v = u;
fv = fu;
}
}
else
{
if (u >= x)
a = x;
else
b = x;
v = w;
w = x;
x = u;
fv = fw;
fw = fx;
fx = fu;
}
}
if(iter > itmax)
cout << "\n Brent exceed maximum iterations.\n\n";
xmin = x;
return fx;
}
vector<double> MyPowell::usePowell()
{
ftol = 1e-4;
vector<vector<double>> xi;
for (int i = 0; i < N; i++)
{
vector<double> xii;
for (int j = 0; j < N; j++)
{
xii.push_back(0);
}
xii[i]=(1.0);
xi.push_back(xii);
}
double fret = 0;
powell(myparams, xi, ftol, fret);
//for (int i = 0; i < xi.size(); i++)
//{
// double a = obj(xi[i]);
// if (fret > a)
// {
// fret = a;
// myparams = xi[i];
// }
//}
cout << "final result" << fret << endl;
return myparams;
}
void MyPowell::erase(vector<double>& pbar, vector<double>& prr, vector<double>& pr)
{
for (int i = 0; i < pbar.size(); i++)
{
pbar[i] = 0;
}
for (int i = 0; i < prr.size(); i++)
{
prr[i] = 0;
}
for (int i = 0; i < pr.size(); i++)
{
pr[i] = 0;
}
}
I used PRAXIS library, because it doesn't need derivative information and is fast.
I modified the code a little to my needs and now it is faster than original version written in Python.

Mac Segmentation fault on Unix Executable File, file compilation is fine [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to run a code scheme published in the following paper:
http://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1001059#s4
Specifically, the implementation of the code is from:
http://www.comp.nus.edu.sg/~rpsysbio/pada/
Following successful compilation of the below code on Mac OS X El Capitan using gcc Fortran, I get an executable file as expected from the code below. However, when I try to execute this file I get
segmentation fault 11.
After some research I think this is a recursion problem causing the stack to overflow, but I have no idea how to solve this. Could someone point me in the right direction please?
#include <stdio.h>
#include <math.h>
#include "./3rdparty/dSFMT-src-2.0/dSFMT.c"
double x1,
x1p,
x1preN;
double x2,
x2p,
x2preN;
double x3,
x3p,
x3preN;
double x4,
x4p,
x4preN;
double k1;
double k2;
double k3;
int x1ctr[100][5][5][5][5][5][5][5];
int x2ctr[100][5][5][5][5][5][5][5];
int x3ctr[100][5][5][5][5][5][5];
int x4ctr[100][5][5][5][5];
double
fx1(double x1)
{
return -(k1 * x1 * x3 - k2 * x2) + k3 * x2;
}
double
fx2(double x2)
{
return (k1 * x1 * x3 - k2 * x2) - k3 * x2;
}
double
fx3(double x3)
{
return -(k1 * x1 * x3 - k2 * x2);
}
double
fx4(double x4)
{
return k3 * x2;
}
int
discretize(double v, double xi[], int length)
{
for (int j = 1; j < length - 1; j++)
if (v < xi[j])
return j - 1;
return length - 2;
}
int
main(int argc, char *argv[])
{
int myid = atoi(argv[1]);
double dt = 0.01,
halfdt = dt / 2.0;
int tps = (int) (10.0 / dt),
t,
i;
int block = tps / 100,
tb;
double halfF1,
halfF2,
F3,
F4;
double x1i[] = { 0.0, 3.0, 6.0, 9.0, 12.0, 15.0 };
double x2i[] = { 0.0, 3.0, 6.0, 9.0, 12.0, 15.0 };
double x3i[] = { 0.0, 3.0, 6.0, 9.0, 12.0, 15.0 };
double x4i[] = { 0.0, 3.0, 6.0, 9.0, 12.0, 15.0 };
int x1pre,
x1post,
x1init = 2;
int x2pre,
x2post,
x2init = 0;
int x3pre,
x3post,
x3init = 4;
int x4pre,
x4post,
x4init = 0;
double k1i[] =
{ 0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0 };
double k2i[] =
{ 0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0 };
double k3i[] =
{ 0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0 };
int k1bin;
int k2bin;
int k3bin;
int sampleNo = 1000;
dsfmt_t dsfmt;
int seed = 7018 + myid;
dsfmt_init_gen_rand(&dsfmt, seed);
for (int i = 0; i < sampleNo; i++) {
k1 = 0.0 + dsfmt_genrand_close_open(&dsfmt) * 1.0;
k2 = 0.0 + dsfmt_genrand_close_open(&dsfmt) * 1.0;
k3 = 0.0 + dsfmt_genrand_close_open(&dsfmt) * 1.0;
x1 = x1i[x1init] +
dsfmt_genrand_close_open(&dsfmt) * (x1i[x1init + 1] -
x1i[x1init]);
x2 = x2i[x2init] +
dsfmt_genrand_close_open(&dsfmt) * (x2i[x2init + 1] -
x2i[x2init]);
x3 = x3i[x3init] +
dsfmt_genrand_close_open(&dsfmt) * (x3i[x3init + 1] -
x3i[x3init]);
x4 = x4i[x4init] +
dsfmt_genrand_close_open(&dsfmt) * (x4i[x4init + 1] -
x4i[x4init]);
x1preN = x1;
x2preN = x2;
x3preN = x3;
x4preN = x4;
k1bin = discretize(k1, k1i, 6);
k2bin = discretize(k2, k2i, 6);
k3bin = discretize(k3, k3i, 6);
for (int t = 1; t <= tps; t++) {
// x1
halfF1 = halfdt * fx1(x1);
halfF2 = halfdt * fx1(x1 + halfF1);
F3 = dt * fx1(x1 + halfF2);
F4 = dt * fx1(x1 + F3);
x1p = x1 + (2 * halfF1 + 4 * halfF2 + 2 * F3 + F4) / 6.0;
// x2
halfF1 = halfdt * fx2(x2);
halfF2 = halfdt * fx2(x2 + halfF1);
F3 = dt * fx2(x2 + halfF2);
F4 = dt * fx2(x2 + F3);
x2p = x2 + (2 * halfF1 + 4 * halfF2 + 2 * F3 + F4) / 6.0;
// x3
halfF1 = halfdt * fx3(x3);
halfF2 = halfdt * fx3(x3 + halfF1);
F3 = dt * fx3(x3 + halfF2);
F4 = dt * fx3(x3 + F3);
x3p = x3 + (2 * halfF1 + 4 * halfF2 + 2 * F3 + F4) / 6.0;
// x4
halfF1 = halfdt * fx4(x4);
halfF2 = halfdt * fx4(x4 + halfF1);
F3 = dt * fx4(x4 + halfF2);
F4 = dt * fx4(x4 + F3);
x4p = x4 + (2 * halfF1 + 4 * halfF2 + 2 * F3 + F4) / 6.0;
if (t % block == 0) {
tb = t / block - 1;
x1pre = discretize(x1preN, x1i, 6);
x2pre = discretize(x2preN, x2i, 6);
x3pre = discretize(x3preN, x3i, 6);
x4pre = discretize(x4preN, x4i, 6);
x1post = discretize(x1, x1i, 6);
x2post = discretize(x2, x2i, 6);
x3post = discretize(x3, x3i, 6);
x4post = discretize(x4, x4i, 6);
x1ctr[tb][k1bin][k2bin][k3bin][x1pre][x2pre][x3pre]
[x1post]++;
x2ctr[tb][k1bin][k2bin][k3bin][x1pre][x2pre][x3pre]
[x2post]++;
x3ctr[tb][k1bin][k2bin][x1pre][x2pre][x3pre][x3post]++;
x4ctr[tb][k3bin][x2pre][x4pre][x4post]++;
x1preN = x1;
x2preN = x2;
x3preN = x3;
x4preN = x4;
}
x1 = x1p;
x2 = x2p;
x3 = x3p;
x4 = x4p;
}
}
// output
FILE *out;
char buffer[256];
snprintf(buffer, sizeof(buffer), "dummy.txt");
int idx = 0;
for (tb = 0; tb < 100; tb++) {
snprintf(buffer, sizeof(buffer),
"./models/toy/batct/toyCTx1T%d_%d.txt", tb, myid);
out = fopen(buffer, "w");
idx = 0;
for (int ki0 = 0; ki0 < 5; ki0++)
for (int ki1 = 0; ki1 < 5; ki1++)
for (int ki2 = 0; ki2 < 5; ki2++)
for (int vi0 = 0; vi0 < 5; vi0++)
for (int vi1 = 0; vi1 < 5; vi1++)
for (int vi2 = 0; vi2 < 5; vi2++)
for (int vi = 0; vi < 5; vi++) {
int ctrtmp =
(x1ctr[tb][ki0][ki1][ki2][vi0][vi1]
[vi2][vi]);
if (ctrtmp > 0) {
fprintf(out, "%d %d\n", idx,
ctrtmp);
}
idx++;
}
fclose(out);
snprintf(buffer, sizeof(buffer),
"./models/toy/batct/toyCTx2T%d_%d.txt", tb, myid);
out = fopen(buffer, "w");
idx = 0;
for (int ki0 = 0; ki0 < 5; ki0++)
for (int ki1 = 0; ki1 < 5; ki1++)
for (int ki2 = 0; ki2 < 5; ki2++)
for (int vi0 = 0; vi0 < 5; vi0++)
for (int vi1 = 0; vi1 < 5; vi1++)
for (int vi2 = 0; vi2 < 5; vi2++)
for (int vi = 0; vi < 5; vi++) {
int ctrtmp =
(x2ctr[tb][ki0][ki1][ki2][vi0][vi1]
[vi2][vi]);
if (ctrtmp > 0) {
fprintf(out, "%d %d\n", idx,
ctrtmp);
}
idx++;
}
fclose(out);
snprintf(buffer, sizeof(buffer),
"./models/toy/batct/toyCTx3T%d_%d.txt", tb, myid);
out = fopen(buffer, "w");
idx = 0;
for (int ki0 = 0; ki0 < 5; ki0++)
for (int ki1 = 0; ki1 < 5; ki1++)
for (int vi0 = 0; vi0 < 5; vi0++)
for (int vi1 = 0; vi1 < 5; vi1++)
for (int vi2 = 0; vi2 < 5; vi2++)
for (int vi = 0; vi < 5; vi++) {
int ctrtmp =
(x3ctr[tb][ki0][ki1][vi0][vi1][vi2]
[vi]);
if (ctrtmp > 0) {
fprintf(out, "%d %d\n", idx, ctrtmp);
}
idx++;
}
fclose(out);
snprintf(buffer, sizeof(buffer),
"./models/toy/batct/toyCTx4T%d_%d.txt", tb, myid);
out = fopen(buffer, "w");
idx = 0;
for (int ki0 = 0; ki0 < 5; ki0++)
for (int vi0 = 0; vi0 < 5; vi0++)
for (int vi1 = 0; vi1 < 5; vi1++)
for (int vi = 0; vi < 5; vi++) {
int ctrtmp =
(x4ctr[tb][ki0][vi0][vi1][vi]);
if (ctrtmp > 0) {
fprintf(out, "%d %d\n", idx, ctrtmp);
}
idx++;
}
fclose(out);
}
return 0;
}
Perhaps there are others, but I see only two things that can generate a crash.
you get the myid integer from this instruction
int myid = atoi(argv[1]);
But if you call the program without passing the id parameter? argv[1] is NULL. Crash!
Suggestion: define a default id and check argc; something like
int myid = (argc > 1 ? atoi(argv[1]) : defId);
you fopen() the output files but you don't check the success of the opening; so, when you write in the files, like in
fprintf(out, "%d %d\n", idx,
ctrtmp);
in case of failure, in opening the file, out is NULL. Crash!
Suggestion: check the opening of the output files (out != NULL).
p.s.: sorry for my bad English.

Negative index runtime error

I am using this as my reference to implement my version of Bicubic interpolation for resizing the images. Here is the function that I have so far with some changes.
IplImage * bicubic(IplImage *img, int newWidth, int newHeight)
{
IplImage *img2 ;
img2 = createImage(newWidth,newHeight);
uchar * data = (uchar*)img->imageData;
uchar * Data = (uchar*)img2->imageData;
//int a,b,c,index;
uchar Cc;
uchar C[5];
uchar d0,d2,d3,a0,a1,a2,a3;
int i,j,k,jj;
int x,y;
float dx,dy;
float tx,ty;
tx = (float)img->width /newWidth ;
ty = (float)img->height / newHeight;
printf("New Width = %d, New Height = %d WidthStep = %d", newWidth, newHeight,img->widthStep);
for(i = 0; i< newHeight; i++)
{
for(j = 0; j< newWidth; j++)
{
x = (int)(tx * j);
y = (int)(ty * i);
dx = tx * j - x;
dy = ty * i - y;
for(k = 0;k < 3;k++)
{
for(jj = 0;jj <= 3 ;jj++)
{
int z = (y - 1 + jj);
//if(z > -1){
a0 = data[z * img->widthStep + (x)*img->nChannels +k];//===>Throws of runtime error
d0 = data[z * img->widthStep + (x-1)*img->nChannels +k] - a0 ;
d2 = data[z * img->widthStep + (x+1)*img->nChannels +k] - a0 ;
d3 = data[z * img->widthStep + (x+2)*img->nChannels +k] - a0 ;
a1 = -1.0/3 * d0 + d2 -1.0/6*d3;
a2 = 1.0/2 * d0 + 1.0/2*d2;
a3 = -1.0/6 * d0 - 1.0/2*d2 + 1.0/6*d3;
C[jj] = a0 + a1*dx + a2*dx*dx + a3*dx*dx*dx;
d0 = C[0]-C[1];
d2 = C[2]-C[1];
d3 = C[3]-C[1];
a0 = C[1];
a1 = -1.0/3*d0 + d2 -1.0/6*d3;
a2 = 1.0/2*d0 + 1.0/2*d2;
a3 = -1.0/6*d0 - 1.0/2*d2 + 1.0/6*d3;
Cc = a0 + a1*dy + a2*dy*dy + a3*dy*dy*dy;
Data[i*img2->widthStep +j*img2->nChannels +k ] = Cc;
//}
}
}
}
}
return img2;
}
The problem that I am facing is that when I call this bicubic function, it throws off an invalid access runtime error at the line where I find out the value of a0. I am using VS 2012 debugger and it tells me that the value of z is calculated as -1. This causes the index to access the invalid part of memory of data array.
My question is, why is this happening? Am I missing something in OpenCV's image library that can help in getting right indices so that I dont run into this error? Or am I making some mistake in accessing the correct indices?
for(i = 0; i< newHeight; i++)
{
for(j = 0; j< newWidth; j++)
{
x = (int)(tx * j);
y = (int)(ty * i);
dx = tx * j - x;
dy = ty * i - y;
for(k = 0;k < 3;k++)
{
for(jj = 0;jj <= 3 ;jj++)
{
int z = (y - 1 + jj);
//if(z > -1){
a0 = data[z * img->widthStep + (x)*img->nChannels +k];//===>Throws of runtime error
d0 = data[z * img->widthStep + (x-1)*img->nChannels +k] - a0 ;
On the first iteration, i and j are 0. as are k and jj
This means that:
y = (int)(ty * i); //y = ty * 0 (== 0)
int z = (y - 1 + jj); //z = 0 - 1 + 0 (==-1)
And so in the line:
a0 = data[z * img->widthStep + (x)*img->nChannels +k];//===>Throws of runtime error
the index is:
(-1) * img->widthStep + (x)*img->nChannels +k
simplifies to:
(-1) * img->widthStep + 0 + 0
which is:
-img->widthStep
This is of course out of bounds, leading to the crash.

My Particle Swarm Optimization code generates different answers in C++ and MATLAB

I have written a global version of Particle Swarm Optimization algorithm in C++.
I tried to write it exactly as same as my MATLAB PSO code that have written before, but this code generates different and so worst answers.
The MATLAB code is:
clear all;
numofdims = 30;
numofparticles = 50;
c1 = 2;
c2 = 2;
numofiterations = 1000;
V = zeros(50, 30);
initialpop = V;
Vmin = zeros(30, 1);
Vmax = Vmin;
Xmax = ones(30, 1) * 100;
Xmin = -Xmax;
pbestfits = zeros(50, 1);
worsts = zeros(50, 1);
bests = zeros(50, 1);
meanfits = zeros(50, 1);
pbests = zeros(50, 30);
initialpop = Xmin + (Xmax - Xmin) .* rand(numofparticles, numofdims);
X = initialpop;
fitnesses = testfunc1(X);
[minfit, minfitidx] = min(fitnesses);
gbestfit = minfit;
gbest = X(minfitidx, :);
for i = 1:numofdims
Vmax(i) = 0.2 * (Xmax(i) - Xmin(i));
Vmin(i) = -Vmax(i);
end
for t = 1:1000
w = 0.9 - 0.7 * (t / numofiterations);
for i = 1:numofparticles
if(fitnesses(i) < pbestfits(i))
pbestfits(i) = fitnesses(i);
pbests(i, :) = X(i, :);
end
end
for i = 1:numofparticles
for j = 1:numofdims
V(i, j) = min(max((w * V(i, j) + rand * c1 * (pbests(i, j) - X(i, j))...
+ rand * c2 * (gbest(j) - X(i, j))), Vmin(j)), Vmax(j));
X(i, j) = min(max((X(i, j) + V(i, j)), Xmin(j)), Xmax(j));
end
end
fitnesses = testfunc1(X);
[minfit, minfitidx] = min(fitnesses);
if(minfit < gbestfit)
gbestfit = minfit;
gbest = X(minfitidx, :);
end
worsts(t) = max(fitnesses);
bests(t) = gbestfit;
meanfits(t) = mean(fitnesses);
end
In which, testfunc1 is:
function [out] = testfunc1(R)
out = sum(R .^ 2, 2);
end
The C++ code is:
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <ctime>
#define rand_01 ((float)rand() / (float)RAND_MAX)
const int numofdims = 30;
const int numofparticles = 50;
using namespace std;
void fitnessfunc(float X[numofparticles][numofdims], float fitnesses[numofparticles])
{
memset(fitnesses, 0, sizeof (float) * numofparticles);
for(int i = 0; i < numofparticles; i++)
{
for(int j = 0; j < numofdims; j++)
{
fitnesses[i] += (pow(X[i][j], 2));
}
}
}
float mean(float inputval[], int vallength)
{
int addvalue = 0;
for(int i = 0; i < vallength; i++)
{
addvalue += inputval[i];
}
return (float)(addvalue / vallength);
}
void PSO(int numofiterations, float c1, float c2,
float Xmin[numofdims], float Xmax[numofdims], float initialpop[numofparticles][numofdims],
float worsts[], float meanfits[], float bests[], float *gbestfit, float gbest[numofdims])
{
float V[numofparticles][numofdims] = {0};
float X[numofparticles][numofdims];
float Vmax[numofdims];
float Vmin[numofdims];
float pbests[numofparticles][numofdims];
float pbestfits[numofparticles];
float fitnesses[numofparticles];
float w;
float minfit;
int minfitidx;
memcpy(X, initialpop, sizeof(float) * numofparticles * numofdims);
fitnessfunc(X, fitnesses);
minfit = *min_element(fitnesses, fitnesses + numofparticles);
minfitidx = min_element(fitnesses, fitnesses + numofparticles) - fitnesses;
*gbestfit = minfit;
memcpy(gbest, X[minfitidx], sizeof(float) * numofdims);
for(int i = 0; i < numofdims; i++)
{
Vmax[i] = 0.2 * (Xmax[i] - Xmin[i]);
Vmin[i] = -Vmax[i];
}
for(int t = 0; t < 1000; t++)
{
w = 0.9 - 0.7 * (float) (t / numofiterations);
for(int i = 0; i < numofparticles; i++)
{
if(fitnesses[i] < pbestfits[i])
{
pbestfits[i] = fitnesses[i];
memcpy(pbests[i], X[i], sizeof(float) * numofdims);
}
}
for(int i = 0; i < numofparticles; i++)
{
for(int j = 0; j < numofdims; j++)
{
V[i][j] = min(max((w * V[i][j] + rand_01 * c1 * (pbests[i][j] - X[i][j])
+ rand_01 * c2 * (gbest[j] - X[i][j])), Vmin[j]), Vmax[j]);
X[i][j] = min(max((X[i][j] + V[i][j]), Xmin[j]), Xmax[j]);
}
}
fitnessfunc(X, fitnesses);
minfit = *min_element(fitnesses, fitnesses + numofparticles);
minfitidx = min_element(fitnesses, fitnesses + numofparticles) - fitnesses;
if(minfit < *gbestfit)
{
*gbestfit = minfit;
memcpy(gbest, X[minfitidx], sizeof(float) * numofdims);
}
worsts[t] = *max_element(fitnesses, fitnesses + numofparticles);
bests[t] = *gbestfit;
meanfits[t] = mean(fitnesses, numofparticles);
}
}
int main()
{
time_t t;
srand((unsigned) time(&t));
float xmin[30], xmax[30];
float initpop[50][30];
float worsts[1000], bests[1000];
float meanfits[1000];
float gbestfit;
float gbest[30];
for(int i = 0; i < 30; i++)
{
xmax[i] = 100;
xmin[i] = -100;
}
for(int i = 0; i < 50; i++)
for(int j = 0; j < 30; j++)
{
initpop[i][j] = rand() % (100 + 100 + 1) - 100;
}
PSO(1000, 2, 2, xmin, xmax, initpop, worsts, meanfits, bests, &gbestfit, gbest);
cout<<"fitness: "<<gbestfit<<endl;
return 0;
}
I have debugged two codes many times but can not find the difference which makes answers different.
It is making me crazy!
May you help me please?
Update:
Please consider that, the function mean is just used for reporting some information and is not used in the optimization procedure.
You've got integer division in the following line
w = 0.9 - 0.7 * (float) (t / numofiterations);
w will be 0.2 for every iteration, change it to
w = 0.9 - 0.7 * t / numofiterations;
The first multiplication will automatically promote t to a double the division should then promote numof iterations to a double.
The parenthesis means it will be done first and therefore not be promoted as wo integers is involved in the division.
This could be a mistake in function mean:
return (float)(addvalue / vallength);
This is integer division, so the result is truncated down, then cast to float. It is unlikely this is what you want.