public static List<Point> CopyImageToAllLocations(SortedList<float, int>[] solutionSet, List<Point> alreadyRendered, Bitmap bmp, Point start, int xCells, int yCells, Dimensions outputDimensions, XIRImage image, Bitmap destination) { int currentID, targetID = image.id; int width = outputDimensions.width; int height = outputDimensions.height; float boxX = (1.0f * width) / xCells; float boxY = (1.0f * height) / yCells; int xActual, yActual; Size currSize = new Size(); float xLoc, yLoc; List<Point> renderedLocations = new List<Point>(0); int avgGrayDiff; for (int x = start.X; x < xCells; x++) { for (int y = start.Y; y < yCells; y++) { currentID = solutionSet[x * yCells + y].Values[0]; avgGrayDiff = XIR.Instance.AverageGrayDiffArray[x * yCells + y]; if (targetID == currentID && !alreadyRendered.Contains(new Point(x,y))) { xLoc = boxX * x; yLoc = boxY * y; xActual = (int)Math.Round(xLoc); yActual = (int)Math.Round(yLoc); currSize.Width = (xLoc + boxX >= width) ? width - xActual - 1 : (int)Math.Round(boxX + xLoc) - xActual; currSize.Height = (yLoc + boxY >= height) ? height - yActual - 1 : (int)Math.Round(boxY + yLoc) - yActual; if (bmp.Size == currSize) { CopyImageInto(destination, bmp, xActual, yActual, avgGrayDiff); renderedLocations.Add(new Point(x, y)); } } } } return renderedLocations; }
/// <summary> /// This function is used to find the best matches for a specific master image cell set. /// </summary> /// <param name="image"></param> /// <param name="images"></param> /// <param name="regionAspectRatio"></param> /// <param name="columns"></param> /// <param name="regionCellWidth"></param> /// <param name="regionCellHeight"></param> /// <param name="numMatchesToReturn"></param> /// <param name="isGrayscale"></param> private void SolveMosaic(XIRImage image, XIRImage[] images, float regionAspectRatio, int columns, int regionCellWidth, int regionCellHeight, int numMatchesToReturn, bool isGrayscale) { float cellAspectRatio; int miWidthInCells, miHeightInCells, ciWidthInCells, ciHeightInCells, width, height; String masterColorArray; XIRPixelationTechnique pixTech; Dimensions dimensions; // Handling a problem that occurs when the master image is to small. image = XIR.Instance.GetXIRImageByAddress(masterImageAddress); dimensions = image.dimensions; width = dimensions.width; height = dimensions.height; cellAspectRatio = image.aspectRatio; int masterId = image.id; pixTech = image.GetMatchingPixelationTechnique(regionAspectRatio, columns); if (pixTech == null) { doPixelationAnalysis(image.address, columns, regionAspectRatio); image = XIR.Instance.GetXIRImageByAddress(image.address); pixTech = image.GetMatchingPixelationTechnique(regionAspectRatio, columns); } miWidthInCells = columns; cellAspectRatio = image.aspectRatio; miHeightInCells = columns; masterColorArray = pixTech.colorArray; #region CUDA variables List<string> candidateImages = new List<string>(); List<int> candidateIDs = new List<int>(); #endregion TimeSpan span = TimeSpan.Zero; // Checking the quality of each match. foreach (XIRImage image1 in images) { Invoke((ThreadStart)delegate { progressForm.progressBar1.Value++; }); image = image1; int cellId = image.id; if (cellId != masterId) { cellAspectRatio = image.aspectRatio; dimensions = image.dimensions; width = dimensions.width; pixTech = image.GetMatchingPixelationTechnique(cellAspectRatio, subdivLevel); float aspectDiff = Math.Abs(regionAspectRatio - cellAspectRatio); if (aspectDiff < 0.005f && pixTech == null) { doPixelationAnalysis(image.address, subdivLevel, cellAspectRatio); //image = XIR.Instance.GetXIRImageByAddress(image.address); pixTech = image.GetMatchingPixelationTechnique(regionAspectRatio, subdivLevel); } if (aspectDiff < 0.005f && pixTech != null) { width = image.dimensions.width; height = image.dimensions.height; ciWidthInCells = subdivLevel;//(int)Math.Round((1.0f * width) / subdivLevel); ciHeightInCells = subdivLevel;// (int)Math.Round(height / (cellWidth / cellAspectRatio)); if (ciWidthInCells == regionCellWidth && ciHeightInCells == regionCellHeight) { #region CUDA variable setup if (useCUDA) { candidateImages.Add(pixTech.colorArray); candidateIDs.Add(cellId); } #endregion #region CPU based cell fitness calculation // Checking every cell location for its fit. if (!useCUDA) { for (int y = 0; y < miHeightInCells && isRunning; y += regionCellHeight) { for (int x = 0; x < miWidthInCells && isRunning; x += regionCellWidth) { DateTime start = DateTime.Now; int diff = ImageCellToRegionDifference(masterColorArray, miWidthInCells, x, y, regionCellWidth, regionCellHeight, pixTech.colorArray, isGrayscale); span += DateTime.Now - start; //TEST TEST TEST TEST TEST TEST TEST TEST TEST //string colorArray = ""; //int index; //for (int i = 0; i < regionCellWidth; i++) //{ // for (int j = 0; j < regionCellHeight; j++) // { // index = 6 * ((i + x) + ((y + j) * miWidthInCells)); // colorArray += masterColorArray.Substring(index, 6); // } //} //XIRToneMap tmpToneMap1 = new XIRToneMap(colorArray, subdivLevel, regionAspectRatio); //XIRToneMap tmpToneMap2 = new XIRToneMap(pixTech); //int diff2 = tmpToneMap1.CalculateDifference(tmpToneMap2); //diff = diff2;// Math.Min(diff, diff2); //TEST TEST TEST TEST TEST TEST TEST TEST TEST int tmpX = x / regionCellWidth; int tmpY = y / regionCellHeight; lock (((ICollection)solutionSet[tmpY * xCells + tmpX]).SyncRoot) { //XIR.Instance.AverageGrayDiffArray[tmpY * xCells + tmpX] = (int)tmpToneMap2.AverageGray - (int)tmpToneMap1.AverageGray; AddToSolution(solutionSet[tmpY * xCells + tmpX], cellId, diff); } } } } #endregion } } } } Console.WriteLine(span.ToString()); #region CUDA calculate solution //DANGER DANGER THIS CAN BLUE SCREEN THE COMPUTER! if (useCUDA) { int[] solutionData = Cuda.CudaProcessor.CUDA_SolveMosaic(masterColorArray, candidateImages, subdivLevel, miWidthInCells / subdivLevel); for (int x = miWidthInCells / subdivLevel - 1; x >= 0; x--) { for (int y = miWidthInCells / subdivLevel - 1; y >= 0; y--) { float minValue = float.MaxValue; int tmpIndex, id = 0, minIndex = 0; for (int n = 0; n < candidateImages.Count; n++) { tmpIndex = (((y * (miWidthInCells / subdivLevel)) + x) * candidateImages.Count) + n; if (solutionData[tmpIndex] < minValue) { minValue = solutionData[tmpIndex]; minIndex = n; id = candidateIDs[n]; } } AddToSolution(solutionSet[(y * (miWidthInCells / subdivLevel)) + x], id, minValue); } } } #endregion }
public XIRImage CreateBasicImageNode(string address, float aspectRatio, DateTime lastModifiedDate, int width, int height, bool validate) { XIRImage image = XIR.Instance.GetXIRImageByAddress(address); bool imageTagIsValid = (image != null) ? ImageStillValid(address) : false; if (image != null && !imageTagIsValid) { //((XmlElement)xir.GetElementsByTagName("images")[0]).RemoveChild(imageElement); //imageElement = null; } if (image == null || !validate) { while (XIR.Instance.Keys.Contains(imageIdIndex)) { imageIdIndex++; } image = new XIRImage(imageIdIndex, aspectRatio, address, lastModifiedDate.ToString(), new Dimensions(width, height)); //XIR.Instance.Add(image.id, image); imageIdIndex++; } return image; }
private void FindImageCellMatchLocations(object parameter) { MosaicInputs mosaicInputs = (MosaicInputs)parameter; int numImages, totalImages = XIR.Instance.Count; XIRImage image = XIR.Instance[mosaicInputs.ImageId]; //Setting up the solution set solutionSet = new SortedList<float, int>[mosaicInputs.Columns * mosaicInputs.Columns]; XIR.Instance.AverageGrayDiffArray = new int[mosaicInputs.Columns * mosaicInputs.Columns]; for (int i = 0; i < solutionSet.Length; i++) { XIR.Instance.AverageGrayDiffArray[i] = 0; solutionSet[i] = new SortedList<float, int>(); solutionSet[i].Capacity = mosaicInputs.ImagesToKeep; } xCells = mosaicInputs.Columns / mosaicInputs.RegionWidth; ///TODO: fix the yCells calculation if we use any other cell count other than s^2 yCells = mosaicInputs.Columns / mosaicInputs.RegionHeight; Invoke((ThreadStart)delegate { progressForm.progressBar1.Minimum = 0; progressForm.progressBar1.Maximum = XIR.Instance.Count; progressForm.progressBar1.Value = 0; progressForm.label1.Text = "Calculating Solution"; progressForm.Visible = true; }); //building our image arrays int imagesPerThread = totalImages / mosaicInputs.NumThreads; int index = 0; XIRImage[][] imagesArray = new XIRImage[mosaicInputs.NumThreads][]; Thread[] solveMosaicThreads = new Thread[mosaicInputs.NumThreads]; for (int thread = 0; thread < mosaicInputs.NumThreads; thread++) { numImages = (thread == 0) ? imagesPerThread + (totalImages % mosaicInputs.NumThreads) : imagesPerThread; imagesArray[thread] = new XIRImage[numImages]; for (int i = numImages - 1; i >= 0; i--) { int key = XIR.Instance.Keys.ElementAt(index++); imagesArray[thread][i] = XIR.Instance[key]; } solveMosaicThreads[thread] = new Thread(SolveMosaic); SolveMosaicInputs inputs = new SolveMosaicInputs(); inputs.image = image; inputs.images = imagesArray[thread]; inputs.regionAspectRatio = mosaicInputs.AspectRatio; inputs.columns = mosaicInputs.Columns; inputs.regionCellWidth = mosaicInputs.RegionWidth; inputs.regionCellHeight = mosaicInputs.RegionHeight; inputs.numMatchesToReturn = mosaicInputs.ImagesToKeep; inputs.isGrayscale = mosaicInputs.Grayscale; solveMosaicThreads[thread].Start(inputs); } int doneCount; do { doneCount = 0; for (int i = 0; i < solveMosaicThreads.Length; i++) { if (solveMosaicThreads[i].ThreadState == ThreadState.Aborted || solveMosaicThreads[i].ThreadState == ThreadState.Stopped) { doneCount++; } //Let the main thread sleep so we don't waste cycles. Thread.Sleep(50); } } while (doneCount != solveMosaicThreads.Length); //Update the XIR file with any new info XIR.Instance.Save(); //Rendering the images to the screen. RenderMosaicPreview(mosaicInputs.Grayscale); }