/// <summary> /// Show image. /// </summary> /// <param name="image"> /// Image to show. /// </param> public void ShowImage(FloatMatrix image) { if (_imgForm == null || _imgForm.IsClosed) _imgForm = ImageForm.ShowImage(image); else _imgForm.SetImage(image); }
/// <summary> /// Creates new <see cref="ImageForm"/> to show specified image. Form use another thread, /// so program is not blocked. /// </summary> /// <param name="image"></param> /// <returns></returns> public static ImageForm ShowImage(FloatMatrix image) { ImageForm form = new ImageForm(image); Thread thread = new Thread(new ThreadStart(form.ThreadFunction)); thread.Start(); return form; }
/// <summary> /// Calculate master flat of specified flat sequence. Function subtract bias from every flat image, /// and returns normed sum of obtained images. /// </summary> /// <param name="flatSequence"> /// Sequence of flat images. /// </param> /// <param name="bias"> /// master bias for flat. /// </param> /// <returns> /// Calculated master flat. /// </returns> public static FloatMatrix MasterFlat(IEnumerable<FloatMatrix> flatSequence, FloatMatrix bias) { FloatMatrix result = SequenceMean(flatSequence); result.Subtract(bias); // Norm flat float pixMean = 0.0f; foreach (float v in result.Data) pixMean += v; result.Divide(pixMean / (float)result.Size); return result; }
/// <summary> /// Convert <see cref="FloatMatrix"/> to <see cref="Bitmap"/>. Only for 2D matrices. /// </summary> /// <param name="matrix"> /// Matrix to convert. /// </param> /// <returns> /// <see cref="Bitmap"/> that represents specified matrix. /// </returns> public Bitmap ToBitmap(FloatMatrix matrix) { if (matrix.Dimensions.Length != 2) throw new ArgumentException("Expected 2D matrix"); int xSize = matrix.Dimensions[0]; int ySize = matrix.Dimensions[1]; int[] tmpArray = new int[xSize * ySize]; Bitmap result; float c = 255.0f / (_max - _min); unsafe { fixed (int* dstPtr = tmpArray) { fixed (float* srcPtr = matrix.Data) { int pos = 0; for (int y = 0; y < ySize; y++) { int rowPos = (ySize - y - 1) * xSize; for (int x = 0; x < xSize; x++) { float ftmp = (srcPtr[pos] - _min) * c; int itmp = (ftmp < 0.0f) ? 0 : (ftmp > 255.0f) ? 255 : (int)ftmp; dstPtr[rowPos] = itmp | (itmp << 8) | (itmp << 16); pos++; rowPos++; } } } result = new Bitmap(matrix.Dimensions[0], matrix.Dimensions[1], matrix.Dimensions[0] * 4, System.Drawing.Imaging.PixelFormat.Format32bppRgb, new IntPtr(dstPtr)); result = result.Clone(new Rectangle(new Point(0, 0), result.Size), System.Drawing.Imaging.PixelFormat.Format24bppRgb); } } return result; }
/// <summary> /// Calculate mean image of sequene (every pixel contains mean of corresponding pixels values from sequence). /// </summary> /// <param name="sequecne"> /// Sequence to calculate mean. Every images have to have same dimensions. /// </param> /// <returns> /// Mean of sequence. /// </returns> public static FloatMatrix SequenceMean(IEnumerable<FloatMatrix> sequecne) { FloatMatrix result = new FloatMatrix(new DataMatrix<float>(sequecne.First().Dimensions)); int num = 0; foreach (FloatMatrix bias in sequecne) { result.Add(bias); num++; } result.Divide((float)num); return result; }
/// <summary> /// Create <see cref="ImageForm"/> that contains specified image. /// </summary> /// <param name="image"> /// Image drawed on form. /// </param> /// <remarks> /// To simple show image use <see cref="ShowImage"/>. /// </remarks> public ImageForm(FloatMatrix image) { SetImage(image); SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true); }
private IEnumerable<FloatMatrix> Debias2(IEnumerable<FloatMatrix> source, int length, FloatMatrix bias1, FloatMatrix bias2) { if (length <= 1) { FloatMatrix bias = bias1 * 0.5f; bias.Add(bias2 * 0.5f); foreach (FloatMatrix image in source) { yield return image - bias; } } else { float a = 1.0f / (float)(length - 1); int n = 0; foreach (FloatMatrix image in source) { float c = (float)n; FloatMatrix bias = bias2 * c; bias.Add(bias1 * (1.0f - c)); yield return image - bias; } } }
private IEnumerable<FloatMatrix> Deflat2(IEnumerable<FloatMatrix> source, int length, FloatMatrix flat1, FloatMatrix flat2) { if (length <= 1) { FloatMatrix flat = flat1 * 0.5f; flat.Add(flat2 * 0.5f); foreach (FloatMatrix image in source) { yield return image / flat; } } else { float a = 1.0f / (float)(length - 1); int n = 0; foreach (FloatMatrix image in source) { float c = (float)n; FloatMatrix flat = flat2 * c; flat.Add(flat1 * (1.0f - c)); yield return image / flat; } } }
/// <summary> /// Set image to draw on form. New image will cover previous, and window will be resized to new image. /// </summary> /// <param name="image"> /// New image to draw on form. /// </param> public void SetImage(FloatMatrix image) { float min = image.Data[0]; float max = min; for (int i = 0; i < image.DataMatrix.Size; i++) { if (min > image.Data[i]) min = image.Data[i]; else if (max < image.Data[i]) max = image.Data[i]; } LinearMatrixDrawer drawer = new LinearMatrixDrawer(min, max); _bitmap = drawer.ToBitmap(image); ClientSize = _bitmap.Size; Refresh(); }
/// <summary> /// Debias data. Subtract master bias from every image in sequence. /// </summary> /// <param name="dataSequence"> /// Data to debias. /// </param> /// <param name="masterBias"> /// Master bias for specified data. /// </param> /// <returns> /// Sequence of debiased data. /// </returns> public static IEnumerable<FloatMatrix> Debias(IEnumerable<FloatMatrix> dataSequence, FloatMatrix masterBias) { return from m in dataSequence select m - masterBias; }
/// <summary> /// Deflat data. Divide every image in sequence by master flat. /// </summary> /// <param name="dataSequence"> /// Data to daflat. /// </param> /// <param name="masterFlat"> /// Master flat for specified data. /// </param> /// <returns> /// Sequence of deflated data. /// </returns> public static IEnumerable<FloatMatrix> Deflat(IEnumerable<FloatMatrix> dataSequence, FloatMatrix masterFlat) { return from m in dataSequence select m / masterFlat; }
private FloatMatrix CalcMeanAndShow(IEnumerable<FloatMatrix> source, string title) { FloatMatrix result = new FloatMatrix(new DataMatrix<float>(source.First().Dimensions)); int n = 0; foreach (FloatMatrix image in source) { n++; _imageWindow.ShowImage(image); _imageWindow.ImgForm.Text = title + " " + n.ToString(); result.Add(image); Wait(_waitOnCalibrationSource); } result.Divide((float)n); return result; }
/// <summary> /// Calculate sum of images in sequene (every pixel contains sum of corresponding pixels values from sequence). /// </summary> /// <param name="sequecne"> /// Sequence to calculate sum. Every images have to have same dimensions. /// </param> /// <returns> /// Sum of sequence. /// </returns> public static FloatMatrix SequenceSum(IEnumerable<FloatMatrix> sequecne) { FloatMatrix result = new FloatMatrix(new DataMatrix<float>(sequecne.First().Dimensions)); foreach (FloatMatrix bias in sequecne) result.Add(bias); return result; }
/// <summary> /// Debias and deflat data. /// </summary> /// <param name="dataSequence"> /// Data to reduct. /// </param> /// <param name="masterBias"> /// Master bias for specified data. /// </param> /// <param name="masterFlat"> /// Master flat for specified data. /// </param> /// <returns> /// Reducted data. /// </returns> public static IEnumerable<FloatMatrix> Reduct(IEnumerable<FloatMatrix> dataSequence, FloatMatrix masterBias, FloatMatrix masterFlat) { return from m in dataSequence select (m - masterBias) / masterFlat; }
/// <summary> /// Norm image. Create new image from specified image, where mean value of pixels is 1. Function does not change source image. /// </summary> /// <param name="image"> /// Image to norm. /// </param> /// <returns> /// Normed image. /// </returns> public static FloatMatrix NormImage(FloatMatrix image) { float pixMean = 0.0f; foreach (float v in image.Data) { pixMean += v; } return image / (pixMean / image.Size); }
/// <summary> /// Track star method /// </summary> /// <remarks> /// Find selected star on image. Updates Position property, when Movable flag is set, and Reference is not null, /// also updates RelPosition property. /// </remarks> /// <param name="image"> /// An image to find selected star. /// </param> /// <exception cref="System.ArgumentException"> /// Thrown when specified image is not 2D matrix. /// </exception> /// <exception cref="SARA.Astrometry.StarEscapedException"> /// Thrown when field where star is looking for is completly out of image. /// </exception> public void Track(FloatMatrix image) { if (image.Dimensions.Length != 2) throw new ArgumentException("Expected 2D matrix"); if (_reference != null) _position = _reference.Position + _relPosition; int minX = (int)(_position.X - _tolerance); int maxX = (int)(_position.X + _tolerance); int minY = (int)(_position.Y - _tolerance); int maxY = (int)(_position.Y + _tolerance); if (maxX < 0 || maxY < 0 || minX >= image.Dimensions[0] || minY >= image.Dimensions[1]) throw new StarEscapedException("Star escaped"); if (minX < 0) minX = 0; if (minY < 0) minY = 0; if (maxX >= image.Dimensions[0]) maxX = image.Dimensions[0] - 1; if (maxY >= image.Dimensions[1]) maxY = image.Dimensions[1] - 1; int pos0 = minY * image.Dimensions[0]; _position = new Vector2D((float)minX, (float)minY); float best = image.Data[pos0 + minX]; for (int y = minY; y <= maxY; y++) { for (int x = minX; x <= maxX; x++) { if (best < image.Data[pos0 + x]) { best = image.Data[pos0 + x]; _position = new Vector2D((float)x, (float)y); } } pos0 += image.Dimensions[0]; } if (_reference != null && _movable) _relPosition = _position - _reference.Position; }
/// <summary> /// Get frame from AVI as 2-dimensional black and white<see cref="SARA.Core.FloatMatrix"/> /// </summary> /// <remarks> /// This function losts information of pixel colors. /// </remarks> /// <param name="frameId"> /// Id of requested frame. /// </param> /// <returns> /// <see cref="SARA.Core.FloatMatrix"/> with requested frame or null. /// </returns> public FloatMatrix GetFloatMatrix(int frameId) { IntPtr frameDBI = AviFil32.AVIStreamGetFrame(_getFrameObj, frameId - (int)_streamInfo.dwStart); if (frameDBI == IntPtr.Zero) throw new AviException("GetFrame returned null frame."); FloatMatrix result; unsafe { int* header = (int*)frameDBI.ToPointer(); result = new FloatMatrix(new DataMatrix<float>(new int[] { header[1], header[2] })); byte *bitmapData = (byte*)(frameDBI.ToInt32() + header[0]); int size = result.DataMatrix.Size; fixed (float* destData = result.Data) { for (int i = 0; i < size; i++) { destData[i] = (float)(bitmapData[0]) + (float)(bitmapData[1]) + (float)(bitmapData[2]); bitmapData += 3; } } } return result; }
private void ShowMaster(FloatMatrix image, string title) { if (_showCalibrationImages) { _imageWindow.ShowImage(image); _imageWindow.ImgForm.Text = title; Wait(_waitOnCalibrationImages); } }