How to make the blackboard text appear clearer using MATLAB? - matlab

What are the sequence of filters I should put if I want the final image to be more clearer with a digital type look. I mean only two distinct colors, one for the board and one for the chalk writing.

When it comes to identifying text in images you better use Stroke Width Transform.
Here's a little result I obtained on your image (the basic transform + connected component w/o filtering):
My mex implementation based on code from here
#include "mex.h"
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <math.h>
using namespace std;
#define PI 3.14159265
struct Point2d {
int x;
int y;
float SWT;
};
struct Point2dFloat {
float x;
float y;
};
struct Ray {
Point2d p;
Point2d q;
std::vector<Point2d> points;
};
void strokeWidthTransform(const float * edgeImage,
const float * gradientX,
const float * gradientY,
bool dark_on_light,
float * SWTImage,
int h, int w,
std::vector<Ray> & rays) {
// First pass
float prec = .05f;
for( int row = 0; row < h; row++ ){
const float* ptr = edgeImage + row*w;
for ( int col = 0; col < w; col++ ){
if (*ptr > 0) {
Ray r;
Point2d p;
p.x = col;
p.y = row;
r.p = p;
std::vector<Point2d> points;
points.push_back(p);
float curX = (float)col + 0.5f;
float curY = (float)row + 0.5f;
int curPixX = col;
int curPixY = row;
float G_x = gradientX[ col + row*w ];
float G_y = gradientY[ col + row*w ];
// normalize gradient
float mag = sqrt( (G_x * G_x) + (G_y * G_y) );
if (dark_on_light){
G_x = -G_x/mag;
G_y = -G_y/mag;
} else {
G_x = G_x/mag;
G_y = G_y/mag;
}
while (true) {
curX += G_x*prec;
curY += G_y*prec;
if ((int)(floor(curX)) != curPixX || (int)(floor(curY)) != curPixY) {
curPixX = (int)(floor(curX));
curPixY = (int)(floor(curY));
// check if pixel is outside boundary of image
if (curPixX < 0 || (curPixX >= w) || curPixY < 0 || (curPixY >= h)) {
break;
}
Point2d pnew;
pnew.x = curPixX;
pnew.y = curPixY;
points.push_back(pnew);
if ( edgeImage[ curPixY*w+ curPixX ] > 0) {
r.q = pnew;
// dot product
float G_xt = gradientX[ curPixY*w + curPixX ];
float G_yt = gradientY[ curPixY*w + curPixX ];
mag = sqrt( (G_xt * G_xt) + (G_yt * G_yt) );
if (dark_on_light){
G_xt = -G_xt/mag;
G_yt = -G_yt/mag;
} else {
G_xt = G_xt/mag;
G_yt = G_yt/mag;
}
if (acos(G_x * -G_xt + G_y * -G_yt) < PI/2.0 ) {
float length = sqrt( ((float)r.q.x - (float)r.p.x)*((float)r.q.x - (float)r.p.x) + ((float)r.q.y - (float)r.p.y)*((float)r.q.y - (float)r.p.y));
for (std::vector<Point2d>::iterator pit = points.begin(); pit != points.end(); pit++) {
float* pSWT = SWTImage + w * pit->y + pit->x;
if (*pSWT < 0) {
*pSWT = length;
} else {
*pSWT = std::min(length, *pSWT);
}
}
r.points = points;
rays.push_back(r);
}
break;
}
}
}
}
ptr++;
}
}
}
bool Point2dSort(const Point2d &lhs, const Point2d &rhs) {
return lhs.SWT < rhs.SWT;
}
void SWTMedianFilter(float * SWTImage, int h, int w,
std::vector<Ray> & rays, float maxWidth = -1 ) {
for (std::vector<Ray>::iterator rit = rays.begin(); rit != rays.end(); rit++) {
for (std::vector<Point2d>::iterator pit = rit->points.begin(); pit != rit->points.end(); pit++) {
pit->SWT = SWTImage[ w*pit->y + pit->x ];
}
std::sort(rit->points.begin(), rit->points.end(), &Point2dSort);
//std::nth_element( rit->points.begin(), rit->points.end(), rit->points.size()/2, &Point2dSort );
float median = (rit->points[rit->points.size()/2]).SWT;
if ( maxWidth > 0 && median >= maxWidth ) {
median = -1;
}
for (std::vector<Point2d>::iterator pit = rit->points.begin(); pit != rit->points.end(); pit++) {
SWTImage[ w*pit->y + pit->x ] = std::min(pit->SWT, median);
}
}
}
typedef std::vector< std::set<int> > graph_t; // graph as a list of neighbors per node
void connComp( const graph_t& g, std::vector<int>& c, int i, int l ) {
// starting from node i labe this conn-comp with label l
if ( i < 0 || i > g.size() ) {
return;
}
std::vector< int > stack;
// push i
stack.push_back(i);
c[i] = l;
while ( ! stack.empty() ) {
// pop
i = stack.back();
stack.pop_back();
// go over all nieghbors
for ( std::set<int>::const_iterator it = g[i].begin(); it != g[i].end(); it++ ) {
if ( c[*it] < 0 ) {
stack.push_back( *it );
c[ *it ] = l;
}
}
}
}
int findNextToLabel( const graph_t& g, const vector<int>& c ) {
for ( int i = 0 ; i < c.size(); i++ ) {
if ( c[i] < 0 ) {
return i;
}
}
return c.size();
}
int connected_components(const graph_t& g, vector<int>& c) {
// check for empty graph!
if ( g.empty() ) {
return 0;
}
int i = 0;
int num_conn = 0;
do {
connComp( g, c, i, num_conn );
num_conn++;
i = findNextToLabel( g, c );
} while ( i < g.size() );
return num_conn;
}
std::vector< std::vector<Point2d> >
findLegallyConnectedComponents(const float* SWTImage, int h, int w,
std::vector<Ray> & rays) {
std::map<int, int> Map;
std::map<int, Point2d> revmap;
std::vector<std::vector<Point2d> > components; // empty
int num_vertices = 0, idx = 0;
graph_t g;
// Number vertices for graph. Associate each point with number
for( int row = 0; row < h; row++ ){
for (int col = 0; col < w; col++ ){
idx = col + w * row;
if (SWTImage[idx] > 0) {
Map[idx] = num_vertices;
Point2d p;
p.x = col;
p.y = row;
revmap[num_vertices] = p;
num_vertices++;
std::set<int> empty;
g.push_back(empty);
}
}
}
if ( g.empty() ) {
return components; // nothing to do with an empty graph...
}
for( int row = 0; row < h; row++ ){
for (int col = 0; col < w; col++ ){
idx = col + w * row;
if ( SWTImage[idx] > 0) {
// check pixel to the right, right-down, down, left-down
int this_pixel = Map[idx];
float thisVal = SWTImage[idx];
if (col+1 < w) {
float right = SWTImage[ w*row + col + 1 ];
if (right > 0 && (thisVal/right <= 3.0 || right/thisVal <= 3.0)) {
g[this_pixel].insert( Map[ w*row + col + 1 ] );
g[ Map[ w*row + col + 1 ] ].insert( this_pixel );
//boost::add_edge(this_pixel, map.at(row * SWTImage->width + col + 1), g);
}
}
if (row+1 < h) {
if (col+1 < w) {
float right_down = SWTImage[ w*(row+1) + col + 1 ];
if (right_down > 0 && (thisVal/right_down <= 3.0 || right_down/thisVal <= 3.0)) {
g[ this_pixel ].insert( Map[ w*(row+1) + col + 1 ] );
g[ Map[ w*(row+1) + col + 1 ] ].insert(this_pixel);
// boost::add_edge(this_pixel, map.at((row+1) * SWTImage->width + col + 1), g);
}
}
float down = SWTImage[ w*(row+1) + col ];
if (down > 0 && (thisVal/down <= 3.0 || down/thisVal <= 3.0)) {
g[ this_pixel ].insert( Map[ w*(row+1) + col ] );
g[ Map[ w*(row+1) + col ] ].insert( this_pixel );
//boost::add_edge(this_pixel, map.at((row+1) * SWTImage->width + col), g);
}
if (col-1 >= 0) {
float left_down = SWTImage[ w*(row+1) + col - 1 ];
if (left_down > 0 && (thisVal/left_down <= 3.0 || left_down/thisVal <= 3.0)) {
g[ this_pixel ].insert( Map[ w*(row+1) + col - 1 ] );
g[ Map[ w*(row+1) + col - 1 ] ].insert( this_pixel );
//boost::add_edge(this_pixel, map.at((row+1) * SWTImage->width + col - 1), g);
}
}
}
}
}
}
std::vector<int> c(num_vertices, -1);
int num_comp = connected_components(g, c);
components.reserve(num_comp);
//std::cout << "Before filtering, " << num_comp << " components and " << num_vertices << " vertices" << std::endl;
for (int j = 0; j < num_comp; j++) {
std::vector<Point2d> tmp;
components.push_back( tmp );
}
for (int j = 0; j < num_vertices; j++) {
Point2d p = revmap[j];
(components[c[j]]).push_back(p);
}
return components;
}
enum {
EIN = 0,
GXIN,
GYIN,
DOLFIN,
MAXWIN,
NIN };
void mexFunction( int nout, mxArray* pout[], int nin, const mxArray* pin[] ) {
//
// make sure images are input in transposed so that they are arranged row-major in memory
//
mxAssert( nin == NIN, "wrong number of inputs" );
mxAssert( nout > 1, "only one output" );
int h = mxGetN( pin[EIN] ); // inputs are transposed!
int w = mxGetM( pin[EIN] );
mxAssert( mxIsClass( pin[EIN], mxSINGLE_CLASS ) && h == mxGetN( pin[EIN] ) && w == mxGetM( pin[EIN] ), "edge map incorrect");
mxAssert( mxIsClass( pin[GXIN], mxSINGLE_CLASS ) && h == mxGetN( pin[GXIN] ) && w == mxGetM( pin[GXIN] ), "edge map incorrect");
mxAssert( mxIsClass( pin[GYIN], mxSINGLE_CLASS ) && h == mxGetN( pin[GYIN] ) && w == mxGetM( pin[GYIN] ), "edge map incorrect");
const float * edgeImage = (float*) mxGetData( pin[EIN] );
const float * gradientX = (float*) mxGetData( pin[GXIN] );
const float * gradientY = (float*) mxGetData( pin[GYIN] );
bool dark_on_light = mxGetScalar( pin[DOLFIN] ) != 0 ;
float maxWidth = mxGetScalar( pin[MAXWIN] );
// allocate output
pout[0] = mxCreateNumericMatrix( w, h, mxSINGLE_CLASS, mxREAL );
float * SWTImage = (float*) mxGetData( pout[0] );
// set SWT to -1
for ( int i = 0 ; i < w*h; i++ ) {
SWTImage[i] = -1;
}
std::vector<Ray> rays;
strokeWidthTransform ( edgeImage, gradientX, gradientY, dark_on_light, SWTImage, h, w, rays );
SWTMedianFilter ( SWTImage, h, w, rays, maxWidth );
// connected components
if ( nout > 1 ) {
// Calculate legally connect components from SWT and gradient image.
// return type is a vector of vectors, where each outer vector is a component and
// the inner vector contains the (y,x) of each pixel in that component.
std::vector<std::vector<Point2d> > components = findLegallyConnectedComponents(SWTImage, h, w, rays);
pout[1] = mxCreateNumericMatrix( w, h, mxSINGLE_CLASS, mxREAL );
float* pComp = (float*) mxGetData( pout[1] );
for ( int i = 0 ; i < w*h; i++ ) {
pComp[i] = 0;
}
for ( int ci = 0 ; ci < components.size(); ci++ ) {
for ( std::vector<Point2d>::iterator it = components[ci].begin() ; it != components[ci].end(); it++ ) {
pComp[ w * it->y + it->x ] = ci + 1;
}
}
}
}
Matlab function calling stroke-width-transform (SWT) mex-file:
function [swt swtcc] = SWT( img, dol, maxWidth )
if size( img, 3 ) == 3
img = rgb2gray(img);
end
img = im2single(img);
edgeMap = single( edge( img, 'canny', .15 ) );
img = imfilter( img, fspecial('gauss',[5 5], 0.3*(2.5-1)+.8) );
gx = imfilter( img, fspecial('prewitt')' ); %//'
gy = imfilter( img, fspecial('prewitt') );
gx = single(medfilt2( gx, [3 3] ));
gy = single(medfilt2( gy, [3 3] ));
[swt swtcc] = swt_mex( edgeMap.', gx.', gy.', dol, maxWidth ); %//'
swt = swt'; %//'
swtcc = double(swtcc'); %//'

Try this :
I = imread('...'); % Your board image
ThreshConstant = 1; % Try to vary this constant.
bw = im2bw(I , ThreshConstant * graythresh(I)); % Black-white image
SegmentedImg = I.*repmat(uint8(bw), [1 1 3]);
Just do imshow(bw); and you will have a 2 color image normally well segmented.
If the threshold is too strong, try to turn around 0.5 to 1.5 with ThreshConstant.

or you could try this
im = imread('http://i.imgur.com/uJIXp13.jpg'); %the image posted above
im2=rgb2gray(im);
maxp=uint16(max(max(im2)));
minp=uint16(min(min(im2)));
bw=im2bw(im2,(double(minp+maxp))/(2*255)); %the threshold as alexandre said, but with the min max idensity as threshold
bw=~bw; % you need to reverse from black font - whit letters to black letters white font :P
imshow(bw)
this should be the result
have in mind , that you can use this technique adaptively with a window, finding the threshold of the window every time for best results.

Related

How to convert HSV to RGB in flutter

I'm using this code to convert RGB to HSV.
now i have to revert back to RGB.
is that any way to convert this in flutter??
I just recently started working in flutter, please help me out, I'm stuck here.
Thank you so much in advance.
rgbToHsv(int r1, int g1, int b1) {
// R, G, B values are divided by 255
// to change the range from 0..255 to 0..1:
double r = r1 / 255.0;
double g = g1 / 255.0;
double b = b1 / 255.0;
// h, s, v = hue, saturation, value
var cmax = [r, g, b].reduce(max); // maximum of r, g, b
var cmin = [r, g, b].reduce(min); // minimum of r, g, b
var diff = cmax - cmin; // diff of cmax and cmin.
var h;
var s;
var v;
//Get value of h
if (cmax == cmin) {
h = 0;
} else if (cmax == r) {
h = (60 * ((g - b) / diff) + 360) % 360;
} else if (cmax == g) {
h = (60 * ((b - r) / diff) + 120) % 360;
} else if (cmax == b) {
h = (60 * ((r - g) / diff) + 240) % 360;
}
//Get value of s
if (cmax == 0) {
s = 0;
} else {
s = (diff / cmax) * 100;
}
//Get value of v
v = cmax * 100;
//Convert HSV [360, 100, 100] to HSV [256, 256, 256]
double h_256 = (h / 360) * 255;
double s_256 = (s / 100) * 255;
double v_256 = (v / 100) * 255;
int h_256_int = h_256.toInt();
int s_256_int = s_256.toInt();
int v_256_int = v_256.toInt();
//Convert to HSV HEX
var hex_h = h_256_int.toRadixString(16);
var hex_s = s_256_int.toRadixString(16);
var hex_v = v_256_int.toRadixString(16);
//MERGE HSV HEX
var finalColor = hex_h + hex_s + hex_v;
print("HSV HEX:" + finalColor.toUpperCase());
/////RGB TRANS>>>>>>>>>>>>>>>>>
////////RGB TRANS>>>>>>>>>>>>>>>>>
////////RGB TRANS>>>>>>>>>>>>>>>>>
////////RGB TRANS>>>>>>>>>>>>>>>>>
var _h = hextToint(hex_h);
var _s = hextToint(hex_s);
var _v = hextToint(hex_v);
print(_h);
print(_s);
print(_v);
print(hsvToRgb(_h.toDouble(), _s.toDouble(), _v.toDouble()));
//return rgb;
}
this might help. I have used this in one of my projects.
String hsvToRgb(double H, double S, double V) {
int R, G, B;
H /= 360;
S /= 100;
V /= 100;
if (S == 0) {
R = (V * 255).toInt();
G = (V * 255).toInt();
B = (V * 255).toInt();
} else {
double var_h = H * 6;
if (var_h == 6) var_h = 0; // H must be < 1
int var_i = var_h.floor(); // Or ... var_i =
// floor( var_h )
double var_1 = V * (1 - S);
double var_2 = V (1 - S (var_h - var_i));
double var_3 = V (1 - S (1 - (var_h - var_i)));
double var_r;
double var_g;
double var_b;
if (var_i == 0) {
var_r = V;
var_g = var_3;
var_b = var_1;
} else if (var_i == 1) {
var_r = var_2;
var_g = V;
var_b = var_1;
} else if (var_i == 2) {
var_r = var_1;
var_g = V;
var_b = var_3;
} else if (var_i == 3) {
var_r = var_1;
var_g = var_2;
var_b = V;
} else if (var_i == 4) {
var_r = var_3;
var_g = var_1;
var_b = V;
} else {
var_r = V;
var_g = var_1;
var_b = var_2;
}
R = (var_r * 255).toInt(); // RGB results from 0 to 255
G = (var_g * 255).toInt();
B = (var_b * 255).toInt();
}
String rs = R.toRadixString(16);
String gs = G.toRadixString(16);
String bs = B.toRadixString(16);
if (rs.length == 1) rs = "0" + rs;
if (gs.length == 1) gs = "0" + gs;
if (bs.length == 1) bs = "0" + bs;
return "#" + rs + gs + bs;
}
RGB to HSV
HSVColor rgbToHSV(int r, int g, int b, {double opacity = 1}) {
return HSVColor.fromColor(Color.fromRGBO(r, g, b, opacity));
}
HSV to RGB
List<int> hsvToRGB(HSVColor color) {
//convert to color
final c = color.toColor();
return [c.red, c.blue, c.green];
}
To use HSVColor use myHSVcolor.toColor().
More about HSV Color.
Expanding on Yeasin Sheikh answer
Flutter
RGB to HSV
HSVColor rgbToHSV(int r, int g, int b, {double opacity = 1}) {
return HSVColor.fromColor(Color.fromRGBO(r, g, b, opacity));
}
HSV to RGB
List<int> hsvToRGB(HSVColor color) {
//convert to color
final c = color.toColor();
return [c.red, c.blue, c.green];
}
To use HSVColor use myHSVcolor.toColor().
More about HSV Color.
Native Dart
Import color package
RGB to HSV
final RgbColor rgbColor = RgbColor(red, green, blue);
final HsvColor hsvColor = rgbColor.toHsvColor();
HSV to RGB
final HsvColor hsvColor = HsvColor(hueValue, saturationValue, valueValue)
final RgbColor rgbColor = hsvColor.toRgbColor();
HSVColor class is not supported in native dart so we are using a package for that with similar classes.

Same C code different results TIv5.2.5 and gcc 5.4.1 c99 compiler

I am using MSP432P401R to do FFT of SAR ADC samples, did FFT in MATLAB and got results same as C compiler online but Code Composer Studio IDE is giving different output than MATLAB results, I thought that can be a compiler issue so tried reading same did some changes and tried but not getting results Like MATLAB.
Online C compiler was gcc 5.4.1 c99.
and in CCS TI v5.2.5 compiler is used.
float m;
float ur, ui, sr, si,tr, ti;
long double Temp_A[256],ArrayA[256]={2676,2840,2838,2832,2826,2818,2814,2808,
2804,2798,2790,2784,2778,2770,2764,2758,2752,2746,2740,2734,
2726,2720,2714,2706,2700,2692,2686,2680,2674,2668,2660,2654,
2646,2642,2634,2624,2618,2612,2604,2598,2590,2584,2576,2570,
2562,2556,2550,2542,2536,2530,2522,2512,2508,2498,2490,2484,
2478,2470,2462,2454,2448,2442,2432,2426,2420,2414,2404,2398,
2390,2382,2374,2368,2360,2352,2346,2338,2330,2322,2314,2306,
2300,2294,2286,2278,2272,2262,2258,2250,2238,2234,2228,2220,
2208,2202,2192,2186,2178,2170,2164,2156,2150,2142,2134,2126,
2116,2110,2104,2096,2088,2078,2070,2062,2054,2046,2040,2034,
2026,2018,2010,2002,1994,1986,1978,1970,1962,1954,1946,1936,
1930,1922,1914,1908,1902,1894,1886,1876,1868,1860,1852,1846,
1838,1830,1822,1814,1804,1796,1790,1784,1776,1768,1760,1754,
1746,1738,1728,1720,1714,1708,1698,1692,1684,1674,1668,1656,
1656,1644,1640,1628,1624,1612,1610,1598,1596,1584,1580,1570,
1564,1554,1546,1540,1532,1526,1520,1512,1504,1496,1490,1482,
1474,1468,1462,1454,1446,1438,1432,1424,1420,1410,1404,1398,
1392,1384,1376,1370,1364,1356,1348,1342,1336,1328,1322,1316,
1308,1300,1294,1286,1280,1276,1270,1262,1254,1248,1242,1236,
1230,1222,1216,1210,1206,1198,1192,1188,1178,1172,1168,1162,
1154,1148,1144,1138,1132,1126,1120,1114,1108,1102,1096,1090,
1084,1080,1074,1068,1062,1058,1052,1048},ArrayA_IMX[256]={0};
unsigned int jm1,i;
unsigned int ip,l;
void main(void)
{
WDT_A->CTL = WDT_A_CTL_PW |WDT_A_CTL_HOLD;
VCORE();
CLK();
P1DIR |= BIT5; //CLK--AD7352 OUTPUT DIRECTION
P1DIR |= BIT7; //CHIP SELECT--AD7352 OUTPUT DIRECTION
P5DIR &= ~BIT0; //SDATAA--AD7352 INPUT DIRECTION P5.0
P5DIR &= ~BIT2; //SDATAB--AD7352 INPUT DIRECTION P5.2
while(1)
{
bit_reversal(ArrayA);
fft(ArrayA,ArrayA_IMX);
}
}
void bit_reversal(long double REX[])
{
int i,i2,n,m;
int tx,k,j;
n = 1;
m=8;
for (i=0;i<m;i++)
{
n *= 2;
}
i2 = n >> 1;
j = 0;
for (i=0;i<n-1;i++)
{
if (i < j)
{
tx = REX[i];
//ty = IMX[i];
REX[i] = REX[j];
//IMX[i] = IMX[j];
REX[j] = tx;
//IMX[j] = ty;
}
k = i2;
while (k <= j)
{
j -= k;
k >>= 1;
}
j += k;
}
}
void fft(long double REX[],long double IMX[])
{
N = 256;
nm1 = N - 1;
nd2 = N / 2;
m = log10l(N) / log10l(2);
j = nd2;
for (l = 1; l <= m; l++)
{
le = powl(2, l);
le2 = le / 2;
ur = 1;
ui = 0;
// Calculate sine and cosine values
sr = cosl(M_PI/le2);
si = -sinl(M_PI/le2);
// Loop for each sub DFT
for (j = 1; j <= le2; j++)
{
jm1 = j - 1;
// Loop for each butterfly
for (i = jm1; i <= nm1; i += le)
{
ip = i + le2;
tr = REX[ip]*ur - IMX[ip]*ui;
ti = REX[ip]*ui + IMX[ip]*ur;
REX[ip] = REX[i] - tr;
IMX[ip] = IMX[i] - ti;
REX[i] = REX[i] + tr;
IMX[i] = IMX[i] + ti;
}
tr = ur;
ur = tr*sr - ui*si;
ui = tr*si + ui*sr;
}
}
}

How to get the hash key?

When I solve this question(149. Max Points on a Line) on leetcode, it have a bug when met this case:
Input [[0,0],[94911151,94911150],[94911152,94911151]]
Output 3
Expected 2
This is my code:
/**
* Definition for a point.
* struct Point {
* int x;
* int y;
* Point() : x(0), y(0) {}
* Point(int a, int b) : x(a), y(b) {}
* };
*/
class Solution {
public:
int maxPoints(vector<Point>& points) {
int size = points.size();
int ans = 0;
if (size == 0) return 0;
unordered_map<double, int> mp;
double k;
for (int i = 0; i < size; ++i) {
int num = 0;
for (int j = i + 1; j < size; ++j) {
if (points[i].x == points[j].x && points[i].y == points[j].y) {
num++;
continue;
}
// my question in below code.
// how can I get the hash key according to slope
if (points[j].x - points[i].x != 0)
k = (double)(points[j].y - points[i].y) / (double)(points[j].x - points[i].x); // calculate the slope.
else k = INT_MAX;
mp[k]++;
}
if (mp[k] == 0) mp[k] = 1, num--;
for (auto it = mp.begin(); it != mp.end(); ++it) {
if (it->second > ans) {
ans = it->second;
ans += num;
}
}
mp.clear();
}
return ans+1;
}
};
In above test case, when it calculate the slope with [0,0] and [94911151,94911150] it comeback k = 1. So I want to know how to get the right hash key to solve this problem?

iRPROP+ Multilayer Perceptron

Hello everyone This is the code of iRPROP+ algo for my MLP. When I try to train my network, standart deviation decreases for 1500 epoches (so slow: from ~0.5 to 0.4732) but suddenly it starts to increase.
Can someone say what did I do wrong?
public void RPROP()
{
double a = 1.2, b = 0.5, nMax = 50, nMin = 0.000001;
for (int l = Network.Length - 1; l > 0; l--)
{
for (int i = 0; i < Network[l].getSize(); i++)
{
Neuron n = Network[l].Neurons[i];
double sum = 0;
if (l == Network.Length - 1) n.Delta = (n.Output - DesiredOutput[i]) * ActFunc.calcDeprivateFunction(n.Output);
else
{
for (int k = 0; k < Network[l + 1].getSize(); k++)
{
sum += Network[l + 1].Neurons[k].getWeight(i) * Network[l + 1].Neurons[k].Delta;
}
n.Delta = sum * ActFunc.calcDeprivateFunction(n.Output);
}
}
}
for (int l = 1; l < Network.Length; l++)
{
for (int i = 0; i < Network[l].getSize(); i++)
{
Neuron n = Network[l].Neurons[i];
if ((n.PrevDelta * n.Delta) > 0)
{
n.N = Math.Min(a * n.PrevN, nMax);
n.Bias -= n.N * Math.Sign(n.Delta);
for (int j = 0; j < Network[l - 1].getSize(); j++)
{
n.setWeight(j, n.getWeight(j) - n.N * Math.Sign(n.Delta));
}
n.PrevDelta = n.Delta;
}
else if ((n.PrevDelta * n.Delta) < 0)
{
n.N = Math.Max(b * n.PrevN, nMin);
if (this.CurrentError > this.LastError)
{
n.Bias += n.PrevN * Math.Sign(n.PrevDelta);
for (int j = 0; j < Network[l - 1].getSize(); j++)
{
n.setWeight(j, n.getWeight(j) + n.PrevN * Math.Sign(n.PrevDelta));
}
}
n.Delta = 0;
}
else if ((n.PrevDelta * n.Delta) == 0)
{
n.Bias -= n.N * Math.Sign(n.Delta);
for (int j = 0; j < Network[l - 1].getSize(); j++)
{
n.setWeight(j, n.getWeight(j) - n.N * Math.Sign(n.Delta));
}
n.PrevDelta = n.Delta;
}
n.PrevN = n.N;
}
}
}
For the first view, you calculate one train element error and you instantly teach it to the network. try to run over the full train set, without change the weights, and just summarize the Delta. After that, update the weights once, set the prev delta and start over.
Also, there is no update for neuron threshold.

Looking for SLAB6 implementation

I'm looking to implement SLAB6 into my raycaster, especially the kv6 support for voxelmodels. However the SLAB6 source by Ken Silverman is totally unreadably (mostly ASM) so I was hoping someone could point me to a proper C / Java source to load kv6 models or maybe to explain me the workings in some pseudocode preferably (since I want to know how to support the kv6, I know how it works). Thanks, Kaj
EDIT: the implementation would be in Java.
I found some code in an application called VoxelGL (author not mentioned in sourcecode):
void CVoxelWorld::generateSlabFromData(unsigned char *data, VoxelData *vdata, Slab *slab)
{
int currentpattern = 1;
int i = 0;
int n, totalcount, v, count;
n = 0;
v = 0;
while (1)
{
while (data[i] == currentpattern)
{
if (currentpattern == 1)
v++;
i++;
if (i == 256)
break;
}
n++;
if (i == 256)
{
if (currentpattern == 0)
n--;
break;
}
currentpattern ^= 1;
}
slab->nentries = n;
if (slab->description != 0)delete [] slab->description;
if (slab->data != 0)delete [] slab->data;
slab->description = new int[n];
slab->data = new VoxelData[v];
totalcount = 0;
v = 0;
currentpattern = 1;
for (i = 0; i < n; i++)
{
count = 0;
while (data[totalcount] == currentpattern)
{
count++;
totalcount++;
if (totalcount == 256)
break;
}
slab->description[i] = count-1;
if (i % 2 == 0)
{
memcpy(slab->data + v, vdata + totalcount - count, 3 * count);
v += count;
}
currentpattern ^= 1;
}
}
And:
#define clustersize 8
Slab *CVoxelWorld::getSlab(int x, int z)
{
int xgrid = x / clustersize;
int ygrid = z / clustersize;
int clusteroffset = xgrid * 1024 * clustersize + ygrid * clustersize * clustersize;
return &m_data[clusteroffset + (x & (clustersize - 1)) + (z & (clustersize - 1)) * clustersize];
}
And:
int CVoxelWorld::isSolid(int x, int y, int z)
{
Slab *slab;
if (y < 0 || y > 256)
return 0;
slab = getSlab(x, z);
int counter = 0;
for (int i = 0; i < slab->nentries; i++)
{
int height = slab->description[i] + 1;
if (i % 2 == 0)
{
if (y >= counter && y < counter + height)
return 1;
}
counter += height;
}
return 0;
}