/// <summary> /// Объединяет сегментированные изображения в одно сегментированное с подавлением шума /// </summary> /// <param name="points">Ключевые точки фона</param> /// <param name="lim">Разброс цвета подложки по поверхности чипа</param> /// <param name="images">Массив несегментированных изображений</param> /// <returns>Объединенное (усредненное) сегментированное изображение с подавлением шума</returns> public static Bitmap UnionOfImages(List<Point> points, int lim, List<Bitmap> images) { int width = images.First().Width; int height = images.First().Height; int[,] res = new int[height, width]; Segmentation segmentation = new Segmentation(points, lim); foreach (Bitmap image in images) { byte[,,] currMas = segmentation.GetSegmentedMass(image); for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) if (currMas[i, j, 0] != 0) res[i, j]++; } byte[,,] outputPicture = new byte[height, width, 3]; for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) ProColors.SetColor(outputPicture, i, j, res[i, j] > 2 ? ProColors.NoWafer : ProColors.Wafer); var noiseSuppression = new NoiseSuppression(outputPicture); outputPicture = noiseSuppression.GetNoiseSuppressedMas(); return ByteToBitmapRgb(outputPicture); }
private void обрезатьToolStripMenuItem_Click(object sender, EventArgs e) { if (CurrResume != Resume.Cutting) return; // сохраняем отступ по которому будет обрезание изображения _offset.X += trbLeftPosition.Value; _offset.Y += trbUpPosition.Value; // определяем позицию текущего изображения на форме int pos = _images.IndexOf(_currImage); // обрезаем изображение на форме _images[pos] = CutBitmapImage(_images[pos], trbLeftPosition.Value, trbRightPosition.Value, trbUpPosition.Value, trbDownPosition.Value); Segmentation segmentationOrigin = new Segmentation(GetCorrectedPoints(), trbToleranceLimit.Value); byte[,,] originMas = segmentationOrigin.GetSegmentedMass(_images[pos]); SuperImposition superImposition = new SuperImposition(originMas); Segmentation segmentation = new Segmentation(_keyPoints, trbToleranceLimit.Value); for (int i = 0; i < _images.Count; i++) { if (i == pos) continue; byte[, ,] currMas = segmentation.GetSegmentedMass(_images[i]); Point offset = superImposition.FindBestImposition(currMas, new Point(trbLeftPosition.Value, trbUpPosition.Value)); _images[i] = CutBitmapImage(_images[i], offset, _images[pos].Width, _images[pos].Height); } _currImage = _images[pos]; pbGoodChipImage.Image = _currImage; // сбрасываем показания контролов trbRightPosition.Value = 0; trbLeftPosition.Value = 0; trbUpPosition.Value = 0; trbDownPosition.Value = 0; RefreshCuttingLabels(); SetDimensionsOfPositionTrackBars(_currImage); }
/// <summary> /// Проверка очередного изображения чипа /// </summary> /// <param name="pathToChipFile">Путь к файлу с изображением чипа</param> /// <returns>Возвращает изображение в формате Bitmap с пометкой подозрительных областей</returns> public void CheckNextChip(string pathToChipFile) { // сегментируем очередной чип, который нужно проверить Bitmap bmp = new Bitmap(pathToChipFile); Segmentation segm = new Segmentation(_cullingProject.KeyPoints, _cullingProject.Lim) { RadiusOfStartFilling = SegmentationRadiusOfStartFilling }; byte[,,] segmentedMass = segm.GetSegmentedMass(bmp); // сохраняем изображение очередного чипа _currChipForTest = bmp; // находим наилучшее совмещение _offset = _superImposition.FindBestImposition(segmentedMass, _cullingProject.OriginOffset); CurrMarkIsland = 0; CurrMarkDust = 0; CountOfDamages = 0; // сравниваем хороший чип и очередной тестируемый CheckChipForDamage(segmentedMass); CurrVerdict = CurrMarkIsland < _sumIslandLimit ? Verdict.Good.Name : Verdict.Bad.Name; }