예제 #1
0
 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;
 }
예제 #2
0
        /// <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
        }
예제 #3
0
        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;
        }
예제 #4
0
        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);
        }