public void WriteLine (FloatMatrix matrix, int z, MatrixLine mask) { int start = (z-matrix.rect.offset.z)*matrix.rect.size.x - matrix.rect.offset.x + offset; for (int x=0; x<length; x++) matrix.arr[start+x] = arr[x] * mask.arr[x]; //matrix[x+offset, z]; }
public static void SpreadBlur (ref MatrixLine curr, ref MatrixLine prev, int blur) { for (int x=0; x<curr.arr.Length; x++) { if (curr.arr[x] > 0.001f) continue; float val = 0; float sum = 0; if (prev.arr[x] > 0.001f) { val += prev.arr[x]; sum++; } for (int i=1; i<=blur; i++) { if (x-i >= 0 && prev.arr[x-i] > 0.001f) { val += prev.arr[x-i]; sum++; } if (x+i < prev.arr.Length-1 && prev.arr[x+i] > 0.001f) { val += prev.arr[x+i]; sum++; } } if (sum != 0) curr.arr[x] = val / sum; } //swapping lines MatrixLine tmp = prev; prev = curr; curr = tmp; }
public void DownsampleBlur (int downsample, float blur, MatrixLine tmpDownsized, MatrixLine tmpBlur) /// both temp lines length is length/downsample { ResampleLinear(this, tmpDownsized); tmpDownsized.GaussianBlur(tmpBlur.arr, blur); ResampleCubic(tmpDownsized, this); }
public void GaussianBlur (float[] tmp, float blur) { int iterations = (int)blur; MatrixLine src = new MatrixLine(arr, 0, length); //for switching arrays between iterations MatrixLine dst = new MatrixLine(tmp, 0, length); //iteration blur for (int i=0; i<iterations; i++) { for (int x=0; x<length; x++) dst.arr[x] = src.AverageSample(x); float[] t = src.arr; src.arr = dst.arr; dst.arr = t; } //last iteration - percentage float percent = blur - iterations; if (percent > 0.0001f) { for (int x=0; x<length; x++) dst.arr[x] = src.AverageSample(x)*percent + src.arr[x]*(1-percent); float[] t = src.arr; src.arr = dst.arr; dst.arr = t; } //copy values to arr for non-even iteration count for (int x=0; x<length; x++) dst.arr[x] = src.arr[x]; }
public void Max (MatrixLine l) { for (int i = 0; i<length; i++) { float v1 = arr[i]; float v2 = l.arr[i]; arr[i] = v1>v2 ? v1 : v2; } }
public static void ResampleCubic (MatrixLine src, MatrixLine dst) /// Scales the line filling dst with interpolated values. Cubic for upscale { for (int x=0; x<dst.length; x++) { float percent = 1.0f * x / dst.length; float sx = percent * src.length; dst.arr[x] = src.CubicSample(sx); } }
public static void DownsampleFast (MatrixLine src, MatrixLine dst, int ratio) /// Scales the line filling dst with interpolated values. Linear for downscale { for (int x=0; x<dst.length; x++) { float sumVal = 0; for (int ix=0; ix<ratio; ix++) sumVal += src.arr[x*ratio + ix]; dst.arr[x] = sumVal / ratio; } }
public static void ResampleLinear (MatrixLine src, MatrixLine dst) /// Scales the line filling dst with interpolated values. Linear for downscale { float radius = 1.0f * src.length / dst.length; for (int x=0; x<dst.length; x++) { float percent = 1.0f * x / dst.length; float sx = percent * src.length; dst.arr[x] = src.LinearSample(sx, radius); } }
public void AppendRow (FloatMatrix matrix, int x, MatrixLine mask) { int start = (offset-matrix.rect.offset.z)*matrix.rect.size.x + x - matrix.rect.offset.x; for (int z=0; z<length; z++) matrix.arr[start + z*matrix.rect.size.x] += arr[z] * mask.arr[z]; }
public void FillGapsOld (int start=0, int end=0, MatrixLine tmpFront=null, MatrixLine tmpBack=null, MatrixLine tmpFrontDist=null, MatrixLine tmpBackDist=null) { if (start==0 && end==0) end = length; if (tmpFront==null) tmpFront = new MatrixLine(offset, length); if (tmpBack==null) tmpBack = new MatrixLine(offset, length); if (tmpFrontDist==null) tmpFrontDist = new MatrixLine(offset, length); if (tmpBackDist==null) tmpBackDist = new MatrixLine(offset, length); //filling front line float prevVal = -1; float prevDist = 0; for (int x=start; x<end; x++) { float val = arr[x]; if (val >= 0) { prevVal = val; prevDist = 0; } tmpFront.arr[x] = prevVal; tmpFrontDist.arr[x] = prevDist; prevDist++; } //extended front line with delta vector - works fine but the result is so-so /*float prevVal = -1; float prevDist = 0; float prevDelta = 0; bool prevEnabled = false; //to avoid calculating delta on single pixels for (int x=0; x<length; x++) { float val = arr[x]; if (val >= 0) { prevDelta = val-prevVal; prevVal = val; prevDist = 0; if (!prevEnabled) prevDelta = 0; //linear delta if prev pixel is a gap prevEnabled = true; } else { prevDist++; prevVal += prevDelta * (1f/prevDist); } tmpFront.arr[x] = prevVal; tmpFrontDist.arr[x] = prevDist; }*/ //back line prevVal = -1; prevDist = 0; for (int x=end-1; x>=start; x--) { float val = arr[x]; if (val >= 0) { prevVal = val; prevDist = 0; } tmpBack.arr[x] = prevVal; tmpBackDist.arr[x] = prevDist; prevDist++; } //blending lines for (int x=start; x<end; x++) { //float val = arr[x]; //if (val >= 0) continue; //float frontVal = tmpFront.arr[x]; //float backVal = tmpBack.arr[x]; float distSum = tmpFrontDist.arr[x] + tmpBackDist.arr[x]; if (distSum == 0) continue; arr[x] = tmpFront.arr[x]*(tmpBackDist.arr[x]/distSum) + tmpBack.arr[x]*(tmpFrontDist.arr[x]/distSum); //note that front and back factors are inverted! } }