public void Start(string value, IProgress <ProgressInfo> progress, CancellationToken cancelToken, PauseToken pauseToken) { var total = 10; var note = ""; for (var i = 0; i < total; i++) { if (cancelToken.IsCancellationRequested) { cancelToken.ThrowIfCancellationRequested(); //throw OperationCanceledException } pauseToken.WaitWhilePausedAsync().GetAwaiter().GetResult(); note += i + " - " + value + "<br/> \n"; var pInfo = new ProgressInfo(); pInfo.Percent = (int)Math.Round(((i + 1) / (double)total) * 100.00, MidpointRounding.AwayFromZero);; pInfo.Note = note; if (progress != null) { progress.Report(pInfo); } Thread.Sleep(1000); } return; }
public async Task StartAsync(IProgress <ProgressInfo> progress, List <int> simpleList, CancellationToken cancelToken, PauseToken pauseToken) { var total = simpleList.Count; var counter = 0; var pInfo = new ProgressInfo(); foreach (var number in simpleList) { if (cancelToken.IsCancellationRequested) { cancelToken.ThrowIfCancellationRequested(); //throw OperationCanceledException } await pauseToken.WaitWhilePausedAsync(); //pause if IsPaused = true //Report progress counter++; pInfo.Percent = (int)Math.Round((counter / (double)total) * 100.00, MidpointRounding.AwayFromZero); if (progress != null) { progress.Report(pInfo); } //Do main job var newnumber = number + 1; Thread.Sleep(2000); } }
private async Task <IGoogleDriveFile> DoCopyFileAsync(IGoogleDriveFile from, IGoogleDriveFolder toFolder, string newName, PauseToken pt, CancellationToken ct, IProgress <GoogleDriveProgress> progress, GoogleDriveProgress progressPayload) { var driveService = await GetDriveServiceAsync().ConfigureAwait(false); progressPayload.Count++; progressPayload.Current = from; progressPayload.Status = string.Format("Copying file '{0}' to folder '{1}'...", from.Name, toFolder.Name); progress.TryReport(() => progressPayload); await pt.WaitWhilePausedAsync().ConfigureAwait(false); var toFile = new File { Parents = new List <string> { toFolder.Id }, Name = newName }; var copyRequest = driveService.Files.Copy(toFile, from.Id); copyRequest.SupportsTeamDrives = true; var resp = await copyRequest.ExecuteAsync(ct).ConfigureAwait(false); var result = new GoogleDriveFile(resp, toFolder); RaiseFileCreated(result); return(result); }
public void Start(IProgress <ProgressInfo> progress, List <TestData> complexList, CancellationToken cancelToken, PauseToken pauseToken) { var total = complexList.Count; var counter = 0; var pInfo = new ProgressInfo(); foreach (var row in complexList) { if (cancelToken.IsCancellationRequested) { cancelToken.ThrowIfCancellationRequested(); //throw OperationCanceledException } pauseToken.WaitWhilePausedAsync().GetAwaiter().GetResult(); //pause if IsPaused = true //Report progress counter++; pInfo.Percent = (int)Math.Round((counter / (double)total) * 100.00, MidpointRounding.AwayFromZero); if (progress != null) { progress.Report(pInfo); } //Do main job var myString = row.MyString; var myNumber = row.MyNumber; Thread.Sleep(2000); } }
public static async Task SomeMethodAsync(PauseToken pause) { for (int i = 0; i < 100; i++) { Console.WriteLine(i); await Task.Delay(100); await pause.WaitWhilePausedAsync(); } }
private async Task SearchImages(string url, CancellationToken cancelToken, PauseToken pauseToken, string folder = null) { string[] links; if (!(url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) ) { url = "http://" + url; } this.txtUrl.Text = url; int attempts = 0; while (true) { await pauseToken.WaitWhilePausedAsync(); if (m_cancel) { return; } links = await m_downloader.GetImageLinks(url); if (links.Length == 0 && m_downloader.HasErrors) { this.ShowLastErrors(); if (++attempts == 10) { break; } } else { break; } } m_links = links; this.clbImageList.BeginUpdate(); this.clbImageList.Items.Clear(); this.clbImageList.Items.AddRange(m_links); this.clbImageList.EndUpdate(); this.tssItemCount.Text = string.Format("Images found: {0}", this.clbImageList.Items.Count); this.ShowLastErrors(); if (m_links.Length > 0) { await this.DownloadImages(cancelToken, pauseToken, folder); } }
public void Start(IProgress <ProgressInfo> progress, int x, CancellationToken cancelToken, PauseToken pauseToken) { var total = 100; //get total for progress var counter = 0; //progress counter var pInfo = new ProgressInfo(); for (var i = 0; i < total; i++) { if (cancelToken.IsCancellationRequested) { cancelToken.ThrowIfCancellationRequested(); //throw OperationCanceledException } pauseToken.WaitWhilePausedAsync().GetAwaiter().GetResult(); //Report progress counter++; var percent = (int)Math.Round((counter / (double)total) * 100.00, MidpointRounding.AwayFromZero); pInfo.Percent = percent; switch (percent) { case 25: pInfo.Note += "Quarter of the way. <br/>"; break; case 50: pInfo.Note += "Half way there. <br/>"; break; case 75: pInfo.Note += "Three fourth of the way. <br/>"; break; case 100: pInfo.Note += "DONE! <br/>Filename: <a href='/downloadfile/internal/234234234.pdf'>tesfile.data</a><br/>"; break; } var tmpDict = new Dictionary <string, string>(); tmpDict.Add("Percent", pInfo.Percent.ToString("##.##")); tmpDict.Add("Note", pInfo.Note); pInfo.Data = JsonConvert.SerializeObject(tmpDict); if (progress != null) { progress.Report(pInfo); } //Do Job x += i; Thread.Sleep(2500); } }
public async IAsyncEnumerable <IFileItem> Search(string path, string pattern, [EnumeratorCancellation] CancellationToken cancellationToken, PauseToken pauseToken) { pattern ??= ""; DirectoryInfo dirInfo = new DirectoryInfo(path); foreach (DirectoryInfo directory in dirInfo.GetDirectories()) { if (cancellationToken.IsCancellationRequested) { yield break; } if (pauseToken.IsPaused) { await pauseToken.WaitWhilePausedAsync(); } IEnumerable <IFileItem> searchedItems = await Search(directory.FullName, pattern, cancellationToken, pauseToken).ToListAsync(); if (searchedItems.Count() > 0) { DirectoryItem item = new DirectoryItem { Name = directory.Name, Path = directory.FullName, Items = searchedItems }; // Имитация задержки поиска файлов await Task.Delay(1); yield return(item); } } foreach (FileInfo file in dirInfo.GetFiles().Where(n => Regex.IsMatch(n.Name, pattern))) { FileItem item = new FileItem { Name = file.Name, Path = file.FullName }; OnFileFound?.Invoke(1); yield return(item); } }
private async Task SomeLongRunningTask(CancellationToken cancellationToken, PauseToken pauseToken) { int count = 10; for (int i = 0; i < count; i++) { cancellationToken.ThrowIfCancellationRequested(); Console.WriteLine($"I'm going to throw an error in {count - i} seconds ..."); await Task.Delay(1000, cancellationToken); await pauseToken.WaitWhilePausedAsync(cancellationToken); } if (!cancellationToken.IsCancellationRequested) { throw new ApplicationException("Simulating an application error"); } }
private async Task <bool> DownloadImages(CancellationToken cancelToken, PauseToken pauseToken, string folder = null) { folder = folder ?? this.txtDestination.Text.Trim(); if (string.IsNullOrWhiteSpace(folder)) { return(false); } this.txtDestination.Text = folder; int processed = 0, len = m_links.Length; while (processed < len) { int result = await m_downloader.DownloadImages(cancelToken, pauseToken, folder, m_links); if (result > 0) { processed += result; } if (m_cancel) { break; } await pauseToken.WaitWhilePausedAsync(); } this.ShowLastErrors(); this.ShowDownloadStatus(); if (this.m_downloader.TotalFilesSaved > 0) { this.tssStatus.Text = " | " + string.Format("{0} images were downloaded.", this.m_downloader.TotalFilesSaved); } return(processed > 0); }
private async Task CheckFile(string address, string fileName, string symbols, IProgress <string> progressFileName, IProgress <string> progressCurFile, IProgress <string> progressPopulate, PauseToken pauseToken, CancellationToken cancelToken) { foreach (var oneFile in Directory.GetFiles(address, "*", SearchOption.AllDirectories)) { await pauseToken.WaitWhilePausedAsync(); if (oneFile != null) { progressCurFile.Report("Текущий файл: " + oneFile); fileChecked++; if (Path.GetFileName(oneFile).Contains(fileName) && File.ReadAllText(oneFile).Contains(symbols)) { progressPopulate.Report(oneFile); fileAdded++; } progressFileName.Report("Файлов обработано:" + fileChecked + "; Файлов найдено: " + fileAdded); } if (cancelToken.IsCancellationRequested) { break; } } }
private async Task BeginGame(GameSettings gameSettings, PauseToken pauseToken, CancellationToken cancellationToken) { _snake = new Snake(gameSettings.Snake); _gameArea = new GameArea(new Point(0, 0), new Point(gameSettings.GameAreaSize.Width, gameSettings.GameAreaSize.Height)); _gameArea.Draw(_writerService); _snake.Draw(_writerService); SpawnNewFood(); WriteScore(); _highLevelEventsService.Start(); var delayInMs = _gameSettings.GetSpeedInMs(); while (true) { await pauseToken.WaitWhilePausedAsync(); if (_skipAutoMove) { _skipAutoMove = false; continue; } Move(this, _lastMoveKeyPressed); if (cancellationToken.IsCancellationRequested) { break; } await Task.Delay(delayInMs); } _highLevelEventsService.Stop(); }
} // end method public async Task<byte[,,]> fdenoiseNeural3(byte[,,] noisyIm, int overlap, string fileName, int layer, int[] networkSize, int numberofsectors, CancellationToken cancelToken, PauseToken pauseToken) { /* * noisyIm: an image corrupted by AWG noise * the sliding window stride of the denoising * process (a smaller stride will usually provide better results). * The pixels of the clean image are assumed to be approximately in * the range 0..255. * overlap: the number of overlaps for two consecutive patches measured in pixels. * Those pixels that are overlapped will be averaged. * fileName: a string which specified the name of the weight file. * layer: Number of layers of the network. * networkSize: Defines the number of neurons in each layer * inputsPerSample: defines the number of inputs in each neuron` */ #region Initialization // determine number of samples and populate them int[] inputsPerSample = new int[layer]; inputsPerSample[0] = networkSize[layer - 1] + 1; for (int i = 1; i < layer; i++) inputsPerSample[i] = networkSize[0] + 1; // end for window.SetText2("Using the Window Step method.\r\n" + Environment.NewLine); window.SetText2("Initializing Components..\r\n" + Environment.NewLine); window.SetProgress1(2); window.SetText2("Loading weights..." + Environment.NewLine); // load the weights Complex[][,] weights = loadMlmvnWeights(fileName, layer, networkSize, inputsPerSample); window.SetText2("Done." + Environment.NewLine); window.SetText2("Configuring Patch Size..."); // size of input / output patch int patchSz = (int)Math.Sqrt(weights[0].GetLength(1)); int patchSzOut = (int)Math.Sqrt(weights[layer - 1].GetLength(0)); // Size of each sector on unit circle window.SetText2("Done.\r\n" + Environment.NewLine); window.SetText2("Input patch size is: " + patchSz + Environment.NewLine); window.SetText2("Output patch size is: " + patchSzOut + Environment.NewLine); // calculate the difference of the patches int p_diff = (patchSz - patchSzOut) / 2; // check if input is larger than output. If so, extend the image int height = noisyIm.GetLength(0); int origHeight = height; int width = noisyIm.GetLength(1); int origWidth = width; int samples = noisyIm.GetLength(2); if (p_diff > 0) { noisyIm = new byte[height + p_diff * 2, width + p_diff * 2, samples]; noisyIm = functions.MirrorImage(noisyIm, height, width, samples, p_diff); // if extended the image, update the size height = noisyIm.GetLength(0); width = noisyIm.GetLength(1); } #region Patch range configuration // calculate how many pixels will be skipped for each patch int interval = patchSz - overlap; // offsetX and offsetY determine the number of "leftover" pixels on the right and bottom edges. int offsetX = (width - patchSz) % interval; int offsetY = (height - patchSz) % interval; // reserve the array to indicate the index of patches. include one position for the fist patch. And reserve extra one position just in case // we need to fill the offset int[] range_x = new int[(width - patchSz) / interval + 2]; int[] range_y = new int[(height - patchSz) / interval + 2]; int pos = 0; // fill the arrays with intervals. ignore the last element because we don't know if it's necessary yet for (int i = 0; i < range_x.GetLength(0) - 1; i++) { range_x[i] = pos; pos += interval; } pos = 0; for (int i = 0; i < range_y.GetLength(0) - 1; i++) { range_y[i] = pos; pos += interval; } // end for // correct last index if necessary // if offsetX and Y are equal to 0, that means no fitting is necessary. Therefore, just resize the array to have // one less length. Else, fill the last element of the array with the index according to the offsets if (offsetX == 0) Array.Resize(ref range_x, range_x.GetLength(0) - 1); else range_x[range_x.GetLength(0) - 1] = width - patchSz; // end if if (offsetY == 0) Array.Resize(ref range_y, range_y.GetLength(0) - 1); else range_y[range_y.GetLength(0) - 1] = height - patchSz; // end if #endregion window.SetText2("\r\nDifference of the patche size is: " + p_diff + Environment.NewLine); window.SetText2("Beginning variable initialization..."); // pre-instantiate complex 2d-arrays // patch of interest byte[,,] cleanIm = new byte[origHeight, origWidth, samples]; byte[,,] counter = new byte[origHeight, origWidth, samples]; // counts the overlapped patch, then later store the processed image. double[,] inputArray = new double[patchSz, patchSz]; Complex[,] CinputArray = new Complex[patchSz, patchSz]; // output patch to be stored to actual image byte[,] outputArray = new byte[patchSz, patchSz]; byte[] output = new byte[(int)Math.Pow(patchSz, 2)]; // used when patch needs to be transformed to 1d array Complex[] S = new Complex[inputArray.Length]; // store outputs of network Complex[][] outputNeurons = new Complex[layer][]; double[] dOutputNeurons = new double[networkSize[layer - 1]]; // instanciate a jagged array to store outputs for (int i = 0; i < layer; i++) outputNeurons[i] = new Complex[networkSize[i]]; // end for Complex sum = new Complex(0, 0); S[0] = new Complex(1, 0); // instantiate imaginary unit Complex complex1 = new Complex(0.0, 1.0); // processIndex as in old code int offset = ((patchSzOut - 3) / 2) + 1; double bb = (2 * Math.PI) / numberofsectors; string[] Channels; switch (samples) { case 1: Channels = new string[] { "" }; break; case 3: Channels = new string[] { "red ", "green ", "blue " }; break; default: Channels = new string[] { "" }; break; } window.SetText2("Done." + Environment.NewLine); window.SetText2("Beginning Processing.\r\n" + Environment.NewLine); #endregion // --------------- Processing Begins ------------------------------ // process each samples for (int k = 0; k < samples; k++) { for (int row = 0; row < range_y.GetLength(0); row++) // for each row { for (int col = 0; col < range_x.GetLength(0); col++) // for each column { #region process first layer // process first layer int ii = 0; byte[,] src = Functions.CreatePatch(noisyIm, range_y[row], range_x[col], k, patchSz); // upcast to double Array.Copy(src, inputArray, src.Length); // transformation of inputs into complex plane for (int i = 0; i < patchSz; i++) for (int j = 0; j < patchSz; j++) CinputArray[i, j] = Exp(complex1 * 2 * Math.PI * inputArray[i, j] / numberofsectors); // end nested for loop // transform to 1d array for (int i = 0; i < patchSz; i++) for (int j = 0; j < patchSz; j++) S[i * patchSz + j] = CinputArray[i, j]; // end for loop #endregion #region calculate weighted sum of first layer and its activation // calculate weighted sum & activation for (int i = 0; i < networkSize[0]; i++) { for (int j = 1; j < inputsPerSample[0]; j++) { sum = sum + weights[ii][i, j] * S[j - 1]; } sum = sum + weights[ii][i, 0]; outputNeurons[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply continuous activation for (int t = 0; t < networkSize[ii]; t++) outputNeurons[ii][t] /= Complex.Abs(outputNeurons[ii][t]); // end for #endregion #region calculate weighted sum of second to last layer // ----------------- Process second to last hidden layers, then output layer for (ii = 1; ii < layer - 1; ii++) { for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * outputNeurons[ii - 1][j - 1]; } sum = sum + weights[ii][i, 0]; outputNeurons[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply contiunous activation for (int t = 0; t < networkSize[ii]; t++) outputNeurons[ii][t] /= Complex.Abs(outputNeurons[ii][t]); // end for } // end for ii // output layer ii = layer - 1; // set to last layer // calculate the weighted sum for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * outputNeurons[ii - 1][j - 1]; } sum = sum + weights[ii][i, 0]; outputNeurons[ii][i] = sum; sum = new Complex(0, 0); } // end for for (int jj = 0; jj < networkSize[ii]; jj++) { // calculate discrete output // get angle dOutputNeurons[jj] = Math.Atan2(outputNeurons[ii][jj].Imaginary, outputNeurons[ii][jj].Real); if (dOutputNeurons[jj] < 0) dOutputNeurons[jj] = 2 * Math.PI + dOutputNeurons[jj]; // end if // round dOutputNeurons[jj] = Math.Truncate(dOutputNeurons[jj] / bb); //dOutputNeurons[jj] = Math.Floor(dOutputNeurons[jj]/bb); if (dOutputNeurons[jj] > 255) if (dOutputNeurons[jj] < 320) dOutputNeurons[jj] = 255; else dOutputNeurons[jj] = 0; // end if // convert results to byte output[jj] = Convert.ToByte(dOutputNeurons[jj]); } // end for #endregion second to last layer #region Process image //// resize //for (int i = 0; i < patchSzOut; i++) // for (int j = 0; j < patchSzOut; j++) // outputArray[i, j] = output[p_diff + j + (i * patchSz)]; //// end for // add to the actual image for (int i = 0; i < patchSzOut; i++) for (int j = 0; j < patchSzOut; j++) { //if (counter[range_y[row] + i, range_x[col] + j] == 0) //{ cleanIm[range_y[row] + i, range_x[col] + j, k] += output[p_diff + j + (i * patchSz)]; // end for //cleanIm[range_y[row] + i, range_x[col] + j, k] += outputArray[i, j]; counter[range_y[row] + i, range_x[col] + j, k]++; //} } // end for #endregion #region Form elements if (cancelToken.IsCancellationRequested) cancelToken.ThrowIfCancellationRequested(); // Action when pause button is clicked await pauseToken.WaitWhilePausedAsync(); window.SetProgress1(1); #endregion } // end col for loop window.SetText2("Patches in " + Channels[k] + "row " + (row + 1) + " of " + range_y.Length + " done." + Environment.NewLine); } // end row for loop } #region Average // Average for (int row = 0; row < origHeight; row++) // for each row { for (int col = 0; col < origWidth; col++) // for each column { for (int k = 0; k < samples; k++) // for each sample { cleanIm[row, col, k] /= counter[row, col, k]; counter[row, col, k] = Convert.ToByte(cleanIm[row, col, k]); } } } #endregion return counter; }
private async Task <IGoogleDriveFile> DoCopyFolderAsync(IGoogleDriveFolder from, IGoogleDriveFolder toFolder, string newName, PauseToken pt, CancellationToken ct, IProgress <GoogleDriveProgress> progress, GoogleDriveProgress progressPayload) { await pt.WaitWhilePausedAsync().ConfigureAwait(false); var name = newName.HasValue() ? newName : from.Name; var getOrCreateFolder = await GetOrCreateFolderAsync(name, toFolder, ct, progress, progressPayload).ConfigureAwait(false); var fromFolderCopy = getOrCreateFolder.Folder; if (fromFolderCopy.IsChildrenCopied.GetValueOrDefault()) { progressPayload.Status = string.Format("Folder '{0}' is already copied", fromFolderCopy.Name); progress.TryReport(() => progressPayload); return(fromFolderCopy); } await pt.WaitWhilePausedAsync().ConfigureAwait(false); progressPayload.Status = string.Format("Loading files under source folder '{0}'", from.Name); progress.TryReport(() => progressPayload); var childFiles = await DoGetChildFilesAsync(from, null, ct, null).ConfigureAwait(false); IReadOnlyCollection <IGoogleDriveFile> childFilesOfCopy = null; if (!getOrCreateFolder.IsNew) { progressPayload.Status = string.Format("Loading files under target folder '{0}'", fromFolderCopy.Name); progress.TryReport(() => progressPayload); childFilesOfCopy = await DoGetChildFilesAsync(fromFolderCopy, null, ct, null).ConfigureAwait(false); } var hasErrors = false; foreach (var file in childFiles) { await pt.WaitWhilePausedAsync().ConfigureAwait(false); if (!ct.IsCancellationRequested) { ////Check existing in memory here instead of letting DoCopyFileAsync to check the file existence by using name to check the target folder - that often throws 400 ApiException. var existing = childFilesOfCopy != null?childFilesOfCopy.FirstOrDefault(i => i.Name == file.Name && i.Size == file.Size) : null; if (existing == null || file is IGoogleDriveFolder) { try { await DoCopyAsync(file, fromFolderCopy, null, pt, ct, progress, progressPayload).ConfigureAwait(false); } catch (Exception ex) { Logger.Error("Error copy file {0} - {1}", from.Name, ex); hasErrors = true; } } else { progressPayload.Count++; progressPayload.Current = existing; progressPayload.Status = string.Format("Found file '{0}' in folder '{1}'...", file.Name, fromFolderCopy.Name); progress.TryReport(() => progressPayload); } } } if (!hasErrors) { await UpdateChildrenCopiedAsync(fromFolderCopy, ct).ConfigureAwait(false); } return(fromFolderCopy); }
/// <summary> /// Convertit un fichier et lance le suivant dans <see cref='FilesToConvert'/>. /// </summary> /// <param name="fichier">Le fichier à convertir.</param> /// <param name="cancellationToken">Jeton d'annulation qui peut être utilisé par d'autres objets ou threads pour être informés de l'annulation.</param> /// <returns>true si la conversion a réussi; sinon false.</returns> public static async Task <string[]> ConvertFile(Fichier fichier, bool finalize = true, CancellationToken cancellationToken = default, PauseToken pauseToken = default) { bool success = false; IEnumerable <string> filesToDelete = null; try { ConversionCount++; await pauseToken.WaitWhilePausedAsync(); if (cancellationToken.IsCancellationRequested || !File.Exists(fichier.Path)) { return(null); } fichier.OriginalState = "FSTATE_Conversion"; var(dspFileNames, channelsCount) = await GetDSPFiles(fichier.Path, VGMStreamProcessTypes.Conversion, 0, cancellationToken, pauseToken); if ((filesToDelete = dspFileNames) == null) { return(null); } var wavFileNames = (await dspFileNames.SelectAsync(dspFile => VGMStream.CreateTempFile("wav", VGMStreamProcessTypes.Conversion), cancellationToken)).ToArray(); filesToDelete = dspFileNames.Concat(wavFileNames); var vgmstreamTmpInfos = new ProcessStartInfo[channelsCount]; var vgmstreamTmpProcess = new Process[channelsCount]; await pauseToken.WaitWhilePausedAsync(); if (cancellationToken.IsCancellationRequested || !File.Exists(App.VGMStreamPath) && !await App.AskVGMStream()) { return(null); //Check VGMStream } for (int i = 0; i < channelsCount && !cancellationToken.IsCancellationRequested; i++) { await Task.Run(() => { pauseToken.WaitWhilePausedAsync(); vgmstreamTmpInfos[i] = VGMStream.StartInfo(dspFileNames[i], wavFileNames[i], fichier.LoopCount, fichier.FadeOut, fichier.FadeDelay, fichier.FadeTime, fichier.StartEndLoop); vgmstreamTmpProcess[i] = Process.Start(vgmstreamTmpInfos[i]); VGMStream.RunningProcess.Add(vgmstreamTmpProcess[i], VGMStreamProcessTypes.Conversion); }); } for (int i = 0; i < vgmstreamTmpProcess.Length; i++) { await vgmstreamTmpProcess[i].WaitForExitAsync(cancellationToken); if (vgmstreamTmpProcess[i].ExitCode != 0) { return(null); } } if (cancellationToken.IsCancellationRequested) { return(null); } try { await Task.Run(() => { var wfrs = wavFileNames.Select(file => new WaveFileReader(file)).ToArray(); var waveProvider = new MultiplexingWaveProvider(wfrs); WaveFileWriter.CreateWaveFile(fichier.FinalDestination, waveProvider); foreach (var wfr in wfrs) { wfr.Close(); } }, cancellationToken); await pauseToken.WaitWhilePausedAsync(); if (!cancellationToken.IsCancellationRequested) { success = true; var data = await vgmstreamTmpProcess[0].StandardOutput.ReadAllLinesAsync().WithCancellation(cancellationToken); var indexOfPath = data.IndexOf(data.FirstOrDefault(s => s.Contains(dspFileNames[0]))); var indexOfChannels = data.IndexOf(data.FirstOrDefault(s => s.Contains("channels"))); var indexOfFormat = data.IndexOf(data.FirstOrDefault(s => s.Contains("metadata from"))); var indexOfBitrate = data.IndexOf(data.FirstOrDefault(s => s.Contains("bitrate"))); data[indexOfPath] = data[indexOfPath].Replace(dspFileNames[0], fichier.Path); data[indexOfChannels] = data[indexOfChannels].Replace("1", channelsCount.ToString()); data[indexOfFormat] = data[indexOfFormat].Replace("Standard Nintendo DSP header", "Retro Studios DKCTF CSMP"); var brp = data[indexOfBitrate].Split(':'); if (brp.Length == 2) { var brs = brp[1].Replace("kbps", string.Empty); var br = brs.ToInt(); if (br != null) { var bitrate = br * channelsCount; data[indexOfBitrate] = data[indexOfBitrate].Replace(br.ToString(), bitrate.ToString()); } } return(data); } else { return(null); } } catch { return(null); } } catch (OperationCanceledException) { return(null); } finally { await VGMStream.DeleteTempFilesByName(filesToDelete); if (success) { fichier.OriginalState = "FSTATE_Completed"; } else if (!cancellationToken.IsCancellationRequested && finalize) { fichier.SetInvalid(); } ConversionCount--; } }
public async Task<Complex[][,]> Learning(string fileNameSamples, int numberOfInputSamples, string fileNameWeights, int layer, int[] networkSize, int[] inputsPerSample, int numberofsectors, double globalThreasholdValue, double localThresholdValue, bool randomWeights, CancellationToken cancelToken, PauseToken pauseToken) { #region Initialization int twoInputsPerSample = networkSize[layer - 1] * 2; window.SetText1("Initializing components..." + Environment.NewLine); // load the samples window.SetText1("Loading learning samples... "); byte[,] samples = loadLearningSamples(fileNameSamples, numberOfInputSamples, twoInputsPerSample); window.SetText1("Done." + Environment.NewLine); // Initial Weights Initialization #region Weights Initialization Random random = new Random(); double real; double imag; Complex[][,] weights = new Complex[layer][,]; if (randomWeights) { // generate random weights // initialize weights matrix for (int ii = 0; ii < layer; ii++) { weights[ii] = new Complex[networkSize[ii], inputsPerSample[ii]]; //if (ii == 0) // weights[ii] = new Complex[networkSize[ii], inputsPerSample[ii]]; //else // weights[ii] = new Complex[networkSize[ii], networkSize[ii - 1]]; // now generate random numbers for (int i = 0; i < weights[ii].GetLength(0); i++) for (int j = 0; j < weights[ii].GetLength(1); j++) { real = random.NextDouble() - 0.5; imag = random.NextDouble() - 0.5; weights[ii][i, j] = new Complex(real, imag); } // end for j // end for i } // end for ii } else { window.SetText1("Loading weights... "); // load the weights weights = loadMlmvnWeights(fileNameWeights, layer, networkSize, inputsPerSample); window.SetText1("Done.\n" + Environment.NewLine); } // end if #endregion double twoPi = Math.PI * 2; Complex complex1 = new Complex(0.0, 1.0); double sectorSize = twoPi / numberofsectors; Complex[] Sector = new Complex[numberofsectors]; for (int i = 0; i < numberofsectors; i++) { double angSector = twoPi * i / numberofsectors; Sector[i] = Complex.Exp(complex1 * angSector); } int numberOfOutputs = networkSize[layer - 1]; int rowInputs = samples.GetLength(0); int colInputs = samples.GetLength(1) / 2; // Desired outputs byte[,] desiredOutputs = new byte[rowInputs, colInputs]; for (int i = 0; i < rowInputs; i++) for (int j = 0; j < colInputs; j++) desiredOutputs[i, j] = samples[i, j + colInputs]; // end for loops // Resized Inputs byte[,] inputs = new byte[rowInputs, colInputs]; for (int i = 0; i < rowInputs; i++) for (int j = 0; j < colInputs; j++) inputs[i, j] = samples[i, j]; // end for loops Complex[,] Cinputs = new Complex[rowInputs, colInputs]; int[,] networkOutputs = new int[rowInputs, colInputs]; //for (int i = 0; i < rowInputs; i++) // for (int j = 0; j < colInputs; j++) // networkOutputs[i, j] = new Complex(0, 0); // end double[] networkErrors = new double[rowInputs]; Complex[][] neuronOutputs = new Complex[layer][]; // instanciate a jagged array to store outputs for (int i = 0; i < layer; i++) neuronOutputs[i] = new Complex[networkSize[i]]; // end for double[] dNeuronOutputs = new double[networkSize[layer - 1]]; Complex[][] neuronErrors = neuronOutputs; Complex[][] weightedSum = new Complex[layer][]; // instanciate a jagged array to store outputs for (int i = 0; i < layer; i++) weightedSum[i] = new Complex[networkSize[i]]; // end for Complex sum = new Complex(0, 0); // transformation of inputs into complex plane for (int i = 0; i < rowInputs; i++) for (int j = 0; j < colInputs; j++) Cinputs[i, j] = Exp(complex1 * 2 * Math.PI * inputs[i, j] / numberofsectors); // end nested for loop // initialize error criteria double mse = 0; double rmse = 0; double[] learningRate; // check if learning is finished bool finishedLearning = false; // counts each cycle int iteration = 0; // output calculation Complex[,] temp; Complex[,] a1; Complex[] b1; Complex[] c1; Complex d1; Complex[,] e1; Complex[,] f1; window.SetText1("Beginning the learning of the weights...\r\n" + Environment.NewLine); #endregion #region RMSE ALGORITHM // repeats process until learning converges while (!finishedLearning) { // increment iteration iteration++; // --------------- BEGIN OUTPUT CALCULATION ------------------------------ #region OUTPUT CALCULATION // process each samples for (int aa = 0; aa < numberOfInputSamples; aa++) // for each row { #region calculate weighted sum of first layer and its activation // process first layer int ii = 0; // calculate weighted sum & activation for (int i = 0; i < networkSize[0]; i++) { for (int j = 1; j < inputsPerSample[0]; j++) { sum = sum + weights[ii][i, j] * Cinputs[aa, j - 1]; } sum = sum + weights[ii][i, 0]; neuronOutputs[ii][i] = sum; //weightedSum[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply continuous activation for (int t = 0; t < networkSize[ii]; t++) neuronOutputs[ii][t] /= Complex.Abs(neuronOutputs[ii][t]); // end for #endregion #region calculate weighted sum of second to last layer // ----------------- Process second to last hidden layers --------------- for (ii = 1; ii < layer - 1; ii++) { for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * neuronOutputs[ii - 1][j - 1]; } sum = sum + weights[ii][i, 0]; neuronOutputs[ii][i] = sum; //weightedSum[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply contiunous activation for (int t = 0; t < networkSize[ii]; t++) neuronOutputs[ii][t] /= Complex.Abs(neuronOutputs[ii][t]); // end for } // end for ii // ----------------- Process output layer -------------------------------- ii = layer - 1; // set to last layer // calculate the weighted sum for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * neuronOutputs[ii - 1][j - 1]; } sum = sum + weights[ii][i, 0]; neuronOutputs[ii][i] = sum; //weightedSum[ii][i] = sum; sum = new Complex(0, 0); } // end for for (int jj = 0; jj < networkSize[ii]; jj++) { // calculate discrete output // get angle dNeuronOutputs[jj] = Math.Atan2(neuronOutputs[ii][jj].Imaginary, neuronOutputs[ii][jj].Real); // if output is less than 0, add 2 pi to make it positive if (dNeuronOutputs[jj] < 0) dNeuronOutputs[jj] = 2 * Math.PI + dNeuronOutputs[jj]; // end if // round dNeuronOutputs[jj] = Math.Truncate(dNeuronOutputs[jj] / sectorSize); //dOutputNeurons[jj] = Math.Floor(dOutputNeurons[jj]/bb); // convert results to byte... did not work correctly, because it could be more than 255. So let it be integer. networkOutputs[aa, jj] = Convert.ToInt32(dNeuronOutputs[jj]); } // end for #endregion second to last layer } // end row for loop #endregion // -------------- END OUTPUT CALCULATION ----------------------------- // -------------- BEGIN NET ERROR CALCULATION ------------------------ #region GLOBAL ERROR CALCULATION // calculate NET error for (int aa = 0; aa < numberOfInputSamples; aa++) { for (int i = 0; i < colInputs; i++) { networkErrors[aa] += Math.Pow((networkOutputs[aa, i] - desiredOutputs[aa, i]), 2); } networkErrors[aa] /= numberOfOutputs; mse += networkErrors[aa]; } // end for aa // calculate mse mse /= numberOfInputSamples; // calculate rmse rmse = Math.Sqrt(mse); window.SetText1("Iteration " + iteration + " done. RMSE: " + rmse + Environment.NewLine); // Check if learning has converged //---> window.TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal; // Action when cancel button is clicked if (cancelToken.IsCancellationRequested) cancelToken.ThrowIfCancellationRequested(); // Action when pause button is clicked await pauseToken.WaitWhilePausedAsync(); if (rmse <= globalThreasholdValue) { finishedLearning = true; window.SetText1("\r\nLearning Converged!!!" + Environment.NewLine); } // end if #endregion // --------------- BEGIN LEARNING / MODIFICATION OF WEIGHTS --------------------------- // LEARNING / MODIFICATION OF WEIGHTS // if the algorithm has not finished learning then output of the // network needs to be calculated again to start correction of // errors #region OUTPUT CALCULATION if (!finishedLearning) { // calculating the output of the network for each sample and // correcting weights if output is > localThresholdValue for (int aa = 0; aa < numberOfInputSamples; aa++) // for each row { #region calculate weighted sum of first layer and its activation // ii holds current layer index. Process first layer int ii = 0; // calculate weighted sum for 1st hidden layer for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * Cinputs[aa, j - 1]; // <-- 7.2 of processing done here } sum = sum + weights[ii][i, 0]; //neuronOutputs[ii][i] = sum; weightedSum[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply continuous activation for (int t = 0; t < networkSize[ii]; t++) neuronOutputs[ii][t] = weightedSum[ii][t] / Complex.Abs(weightedSum[ii][t]); // end for #endregion #region calculate weighted sum of second to last hidden layer // ----------------- Process second to last hidden layers, then output layer // ii holds current layer for (ii = 1; ii < layer - 1; ii++) { for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * neuronOutputs[ii - 1][j - 1]; } sum = sum + weights[ii][i, 0]; //neuronOutputs[ii][i] = sum; weightedSum[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply continuous activation for (int t = 0; t < networkSize[ii]; t++) neuronOutputs[ii][t] = weightedSum[ii][t] / Complex.Abs(weightedSum[ii][t]); // end for } // end for ii #endregion #region calculate output layer and network output calculation // output layer ii = layer - 1; // set to last layer // calculate the weighted sum for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * neuronOutputs[ii - 1][j - 1]; // <-- 5.8 of processing is done here } sum = sum + weights[ii][i, 0]; neuronOutputs[ii][i] = sum; weightedSum[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply the activation function for discrete outputs for (int jj = 0; jj < networkSize[ii]; jj++) { // Action when cancel button is clicked if (cancelToken.IsCancellationRequested) cancelToken.ThrowIfCancellationRequested(); // Action when pause button is clicked await pauseToken.WaitWhilePausedAsync(); // calculate discrete output // get angle dNeuronOutputs[jj] = Math.Atan2(weightedSum[ii][jj].Imaginary, weightedSum[ii][jj].Real); // if output is less than 0, add 2 pi to make it positive if (dNeuronOutputs[jj] < 0) dNeuronOutputs[jj] = 2 * Math.PI + dNeuronOutputs[jj]; // end if // round dNeuronOutputs[jj] = Math.Truncate(dNeuronOutputs[jj] / sectorSize); //dOutputNeurons[jj] = Math.Floor(dOutputNeurons[jj]/bb); // convert results to byte... did not work correctly, because it could be more than 255. So let it be integer. networkOutputs[aa, jj] = Convert.ToInt32(dNeuronOutputs[jj]); } // end for #endregion second to last layer #region R/MSE SPECIFIC CALCULATION OF ERROR // calculate NET error for (int i = 0; i < colInputs; i++) { networkErrors[aa] += Math.Pow((networkOutputs[aa, i]) - desiredOutputs[aa, i], 2); } networkErrors[aa] /= numberOfOutputs; // calculate rmse networkErrors[aa] = Math.Sqrt(networkErrors[aa]); #endregion #region Weights Modification // check agains local threshold // if localThresholdValue is greater, then the weights are corrected if (localThresholdValue < networkErrors[aa]) { // Action when cancel button is clicked if (cancelToken.IsCancellationRequested) cancelToken.ThrowIfCancellationRequested(); // Action when pause button is clicked await pauseToken.WaitWhilePausedAsync(); #region ERROR CALCULATION // CALCULATE THE ERROR OF THE NEURONS // calculation of the errors of neurons starts at last layer // and moves to first layer ii = layer - 1; // outputs will contain normalized weighted sums for all output neurons for (int t = 0; t < networkSize[ii]; t++) neuronOutputs[ii][t] = weightedSum[ii][t] / Complex.Abs(weightedSum[ii][t]); // end for // the global error for the jjj-th output neuron // equals a root of unity corresponding to the // desired output - normalized weighted sum for // the corresponding output neuron for (int jjj = 0; jjj < networkSize[ii]; jjj++) neuronErrors[ii][jjj] = Sector[desiredOutputs[aa, jjj]] - neuronOutputs[ii][jjj]; // end for // finally we obtain the output neurons' errors // normalizing the global errors (dividing them // by the (number of neurons in the preceding // layer+1) for (int t = 0; t < networkSize[ii]; t++) neuronErrors[ii][t] = neuronErrors[ii][t] / (networkSize[ii - 1] + 1); // end for // ------------- HANDLING THE REST OF LAYERS - ERROR BACKPROPAGATION ------------ for (ii = layer - 2; -1 < ii; ii--) { // calculate the reciprocal weights for the layer ii and putting them in // a vector-row temp = new Complex[weights[ii + 1].GetLength(1) - 1, weights[ii + 1].GetLength(0)]; for (int i = 1; i < temp.GetLength(0) + 1; i++) //511 for (int j = 0; j < temp.GetLength(1); j++) //169 temp[i - 1, j] = 1 / weights[ii + 1][j, i]; // <-- 23.5 of processing done here //end fors // confirmed bug free above this point... 5/2/2014 0:48 sum = new Complex(0, 0); // backpropagation of weights if (0 < ii) // all hidden layers except the 1st for (int row = 0; row < temp.GetLength(0); row++) { for (int col = 0; col < temp.GetLength(1); col++) { sum = sum + temp[row, col] * neuronErrors[ii + 1][col]; } neuronErrors[ii][row] = sum / (networkSize[ii - 1] + 1); sum = new Complex(0, 0); // end for } // end for else for (int row = 0; row < temp.GetLength(0); row++) { for (int col = 0; col < temp.GetLength(1); col++) { sum = sum + temp[row, col] * neuronErrors[ii + 1][col]; } neuronErrors[ii][row] = sum / (inputsPerSample[0]); sum = new Complex(0, 0); // end for } // end for // end if } // end ii for loop over the layers #endregion #region WEIGHTS CORRECTION // -------------- CORRECTS THE WEIGHTS OF THE NETWORK ---------------------------------- // HANDLING THE 1ST HIDDEN LAYER // learning rate is a reciprocal absolute value of the weighted sum learningRate = new double[weightedSum[0].GetLength(0)]; for (int i = 0; i < learningRate.GetLength(0); i++) learningRate[i] = (1 / Complex.Abs(weightedSum[0][i])); // end for // take learning rate into account // for all weights except bias w0 for (int row = 0; row < networkSize[0]; row++) for (int col = 1; col < inputsPerSample[0]; col++) weights[0][row, col] = weights[0][row, col] + (learningRate[row] * neuronErrors[0][row]) * Complex.Conjugate(Cinputs[aa, col - 1]); // end for for (int row = 0; row < networkSize[0]; row++) weights[0][row, 0] = weights[0][row, 0] + (learningRate[row] * neuronErrors[0][row]); // end for // correct the following layers for (ii = 1; ii < layer; ii++) { sum = new Complex(0, 0); // calculate the new output of preceding layer // if preceding layer is the 1st one if (ii == 1) { // calculate weighted sum for (int i = 0; i < networkSize[0]; i++) { for (int j = 1; j < inputsPerSample[0]; j++) { sum = sum + weights[0][i, j] * Cinputs[aa, j - 1]; } sum = sum + weights[0][i, 0]; weightedSum[0][i] = sum; sum = new Complex(0, 0); } // end for } // end if else // if a preceding layer is not the 1st one { // calculate weighted sum & activation for (int i = 0; i < networkSize[ii - 1]; i++) { for (int j = 1; j < inputsPerSample[ii - 1]; j++) { sum = sum + weights[ii - 1][i, j] * neuronOutputs[ii - 2][j - 1]; } sum = sum + weights[ii - 1][i, 0]; weightedSum[ii - 1][i] = sum; sum = new Complex(0, 0); } // end for } // end if // CONTINUOUS OUTPUT CALCULATION for (int t = 0; t < networkSize[ii - 1]; t++) neuronOutputs[ii - 1][t] = weightedSum[ii - 1][t] / Complex.Abs(weightedSum[ii - 1][t]); // end for // learning rate is the reciprocal absolute value of the weighted sum learningRate = new double[weightedSum[ii].GetLength(0)]; for (int i = 0; i < learningRate.GetLength(0); i++) learningRate[i] = (1 / Complex.Abs(weightedSum[ii][i])); // end for // learning rate not used for the output layer neurons if (ii < layer) // <-- ~10 of processing done here (partly due to complex calculations) { // do last things a1 = (Complex[,])weights[ii].Clone(); b1 = (Complex[])neuronErrors[ii].Clone(); for (int i = 0; i < b1.GetLength(0); i++) b1[i] = b1[i] * learningRate[i]; // end for c1 = (Complex[])neuronOutputs[ii - 1].Clone(); for (int i = 0; i < c1.GetLength(0); i++) c1[i] = Complex.Conjugate(c1[i]); // end for e1 = (Complex[,])a1.Clone(); for (int i = 0; i < networkSize[ii]; i++) { d1 = b1[i]; for (int j = 1; j < a1.GetLength(1); j++) e1[i, j] = d1 * c1[j - 1]; } f1 = new Complex[a1.GetLength(0), a1.GetLength(1) - 1]; for (int i = 0; i < a1.GetLength(0); i++) for (int j = 1; j < a1.GetLength(1); j++) f1[i, j - 1] = a1[i, j] + e1[i, j]; // end for for (int i = 0; i < weights[ii].GetLength(0); i++) for (int j = 1; j < weights[ii].GetLength(1); j++) weights[ii][i, j] = f1[i, j - 1]; // end for for (int i = 0; i < weights[ii].GetLength(0); i++) weights[ii][i, 0] = weights[ii][i, 0] + (learningRate[i] * neuronErrors[ii][i]); // end for } else { // do last things a1 = (Complex[,])weights[ii].Clone(); b1 = (Complex[])neuronErrors[ii].Clone(); c1 = (Complex[])neuronOutputs[ii - 1].Clone(); for (int i = 0; i < c1.GetLength(0); i++) c1[i] = Complex.Conjugate(c1[i]); // end for e1 = (Complex[,])a1.Clone(); for (int i = 0; i < networkSize[ii]; i++) { d1 = b1[i]; for (int j = 1; j < a1.GetLength(1); j++) e1[i, j] = d1 * c1[j - 1]; } f1 = new Complex[a1.GetLength(0), a1.GetLength(1) - 1]; for (int i = 0; i < a1.GetLength(0); i++) for (int j = 1; j < a1.GetLength(1); j++) f1[i, j - 1] = a1[i, j] + e1[i, j]; // end for for (int i = 0; i < weights[ii].GetLength(0); i++) for (int j = 1; j < weights[ii].GetLength(1); j++) weights[ii][i, j] = f1[i, j - 1]; // end for for (int i = 0; i < weights[ii].GetLength(0); i++) weights[ii][i, 0] = weights[ii][i, 0] + neuronErrors[ii][i]; // end for } // end if } // end ii for #endregion #endregion } // end localThresholdValue if check } // end aa for loop } // end ~finishedLearning if statement #endregion }// end ~finishedLearning while loop #endregion return weights; }
} // end method public async Task<byte[,,]> fdenoiseNeural2(byte[,,] noisyIm, int step, string fileName, int layer, int[] networkSize, int[] inputsPerSample, int numberofsectors, CancellationToken cancelToken, PauseToken pauseToken)//, double progressBar1, double progressBar1Max) { /* * noisyIm: an image corrupted by AWG noise * the sliding window stride of the denoising process (a smaller stride will usually provide better results). The pixels of the clean image are assumed to be approximately in the range 0..255. */ #region Initialization window.SetText2("Using the new patch method.\r\n" + Environment.NewLine); window.SetText2("Initializing Components...\r\n" + Environment.NewLine); window.SetProgress1(2); window.SetText2("Loading weights... "); // load the weights Complex[][,] weights = loadMlmvnWeights(fileName, layer, networkSize, inputsPerSample); window.SetText2("Done." + Environment.NewLine); window.SetText2("Configuring Patch Size... "); // size of input / output patch int patchSz = (int)Math.Sqrt(weights[0].GetLength(1)); int patchSzOut = (int)Math.Sqrt(weights[layer - 1].GetLength(0)); // Size of each sector on unit circle window.SetText2("Done.\r\n" + Environment.NewLine); window.SetText2("Input patch size is: " + patchSz + Environment.NewLine); window.SetText2("Output patch size is: " + patchSzOut + Environment.NewLine); // calculate the difference of the patches int p_diff = (patchSz - patchSzOut) / 2; // check if input is larger than output. If so, extend the image int height = noisyIm.GetLength(0); int origHeight = height; int width = noisyIm.GetLength(1); int origWidth = width; int samples = noisyIm.GetLength(2); if (p_diff > 0) { noisyIm = new byte[height + p_diff * 2, width + p_diff * 2, samples]; noisyIm = functions.MirrorImage(noisyIm, height, width, samples, p_diff); // if extended the image, update the size height = noisyIm.GetLength(0); width = noisyIm.GetLength(1); } #region Patch range configuration // interval determines how many pixels would be skipped before new patch will be placed. // For example, if step is 3 and patch size is 13, 3 * 2 = 6 pixels would be overlapped for non-edge patches. // Therefore, 13 - 6 = 7 pixels will be skipped. int interval = patchSz - (step * 2); // offsetX and offsetY determine the number of "leftover" pixels on the right and bottom edges. // For example, if 512 * 512 image will be filled by 13 * 13 patches, 512 - ((13-3) % interval int offsetX = (width - (patchSz - step)) % interval; int offsetY = (height - (patchSz - step)) % interval; // reserve the array to indicate the index of patches. include one position for the fist patch. And reserve extra one position just in case // we need to fill the offset int[] range_x = new int[(width - (patchSz - step)) / interval + 2]; int[] range_y = new int[(height - (patchSz - step)) / interval + 2]; int pos = 0; // fill the arrays with intervals. ignore the last element because we don't know if it's necessary yet for (int i = 0; i < range_x.GetLength(0) - 1; i++) { range_x[i] = pos; pos += interval; } pos = 0; for (int i = 0; i < range_y.GetLength(0) - 1; i++) { range_y[i] = pos; pos += interval; } // end for // correct last index if necessary // if offsetX and Y are equal to 0, that means no fitting is necessary. Therefore, just resize the array to have // one less length. Else, fill the last element of the array with the index according to the offsets if (offsetX == 0) Array.Resize(ref range_x, range_x.GetLength(0) - 1); else range_x[range_x.GetLength(0) - 1] = width - patchSz; // end if if (offsetY == 0) Array.Resize(ref range_y, range_y.GetLength(0) - 1); else range_y[range_y.GetLength(0) - 1] = height - patchSz; // end if #endregion window.SetText2("\r\nDifference of the patche size is: " + p_diff + Environment.NewLine); window.SetText2("Beginning variable initialization... "); // pre-instantiate complex 2d-arrays // patch of interest byte[,,] cleanIm = new byte[origHeight, origWidth, samples]; //byte[,] counter = new byte[origHeight, origWidth]; // counts the overlapped patch, then later store the processed image. double[,] inputArray = new double[patchSz, patchSz]; Complex[,] CinputArray = new Complex[patchSz, patchSz]; // output patch to be stored to actual image byte[,] outputArray = new byte[patchSz, patchSz]; byte[] output = new byte[Convert.ToInt32(Math.Pow(patchSz, 2))]; // used when patch needs to be transformed to 1d array Complex[] S = new Complex[inputArray.Length]; // store outputs of network Complex[][] outputNeurons = new Complex[layer][]; double[] dOutputNeurons = new double[networkSize[layer - 1]]; // instanciate a jagged array to store outputs for (int i = 0; i < layer; i++) outputNeurons[i] = new Complex[networkSize[i]]; // end for Complex sum = new Complex(0, 0); S[0] = new Complex(1, 0); // instantiate imaginary unit Complex complex1 = new Complex(0.0, 1.0); // processIndex as in old code int offset = ((patchSzOut - 3) / 2) + 1; double bb = (2 * Math.PI) / numberofsectors; string[] Channels; switch (samples) { case 1: Channels = new string[] {""}; break; case 3: Channels = new string[] {"red ", "green ", "blue "}; break; default: Channels = new string[] { "" }; break; } window.SetText2("Done.\r\n" + Environment.NewLine); window.SetText2("Beginning Processing... \r\n" + Environment.NewLine); #endregion // --------------- Processing Begins ------------------------------ // process each samples for (int k = 0; k < samples; k++) { for (int row = 0; row < range_y.GetLength(0); row++) // for each row { for (int col = 0; col < range_x.GetLength(0); col++) // for each column { #region process first layer // process first layer int ii = 0; byte[,] src = Functions.CreatePatch(noisyIm, range_y[row], range_x[col], k, patchSz); // upcast to double Array.Copy(src, inputArray, src.Length); // transformation of inputs into complex plane for (int i = 0; i < patchSz; i++) for (int j = 0; j < patchSz; j++) CinputArray[i, j] = Exp(complex1 * 2 * Math.PI * inputArray[i, j] / numberofsectors); // end nested for loop // transform to 1d array for (int i = 0; i < patchSz; i++) for (int j = 0; j < patchSz; j++) S[i * patchSz + j] = CinputArray[i, j]; // end for loop #endregion #region calculate weighted sum of first layer and its activation // calculate weighted sum & activation for (int i = 0; i < networkSize[0]; i++) { for (int j = 1; j < inputsPerSample[0]; j++) { sum = sum + weights[ii][i, j] * S[j - 1]; } sum = sum + weights[ii][i, 0]; outputNeurons[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply continuous activation for (int t = 0; t < networkSize[ii]; t++) outputNeurons[ii][t] /= Complex.Abs(outputNeurons[ii][t]); // end for #endregion #region calculate weighted sum of second to last layer // ----------------- Process second to last hidden layers, then output layer for (ii = 1; ii < layer - 1; ii++) { for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * outputNeurons[ii - 1][j - 1]; } sum = sum + weights[ii][i, 0]; outputNeurons[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply contiunous activation for (int t = 0; t < networkSize[ii]; t++) outputNeurons[ii][t] /= Complex.Abs(outputNeurons[ii][t]); // end for } // end for ii // output layer ii = layer - 1; // set to last layer // calculate the weighted sum for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * outputNeurons[ii - 1][j - 1]; } sum = sum + weights[ii][i, 0]; outputNeurons[ii][i] = sum; sum = new Complex(0, 0); } // end for for (int jj = 0; jj < networkSize[ii]; jj++) { // calculate discrete output // get angle dOutputNeurons[jj] = Math.Atan2(outputNeurons[ii][jj].Imaginary, outputNeurons[ii][jj].Real); if (dOutputNeurons[jj] < 0) dOutputNeurons[jj] = 2 * Math.PI + dOutputNeurons[jj]; // end if // round dOutputNeurons[jj] = Math.Truncate(dOutputNeurons[jj] / bb); //dOutputNeurons[jj] = Math.Floor(dOutputNeurons[jj]/bb); if (dOutputNeurons[jj] > 255) if (dOutputNeurons[jj] < 320) dOutputNeurons[jj] = 255; else dOutputNeurons[jj] = 0; // end if // convert results to byte output[jj] = Convert.ToByte(dOutputNeurons[jj]); } // end for #endregion second to last layer #region Process image // resize for (int i = 0; i < patchSzOut; i++) for (int j = 0; j < patchSzOut; j++) outputArray[i, j] = output[p_diff + j + (i * patchSz)]; // end for // Output to an acutal image. /* Codes below outputs the calculated patch into the output image. Although the size of patch is 13 x 13, only center 7 * 7 will be copied to the * image because of overlapping method, with the only exception of when the patch touches the edge of the image. In order to determine this, we will * first check whether the coordinate of the patch is either 0 or width(height) - patchSz. if so, we need to take the borders into account. Otherwise, * we just need to copy center 7 x 7 pixels onto corresponding coordinates. */ // check if (range_y[row] == 0 || range_y[row] == height - patchSz || range_x[col] == 0 || range_x[col] == width - patchSz) { // startY and startX determines the starting coordinate of the local patch; it's initialized with step. if the patch is touching the edge, we need to // set them to 0, so whole patch side will be copied. The same for endY and endX. int startY, startX; startY = startX = step; int endY, endX; endY = endX = patchSzOut - step; // All outer patches if (range_y[row] == 0) startY = 0; // end if if (range_y[row] == height - patchSz) { // startY = patchSzOut - (height - (range_y[row - 1] + patchSz - (step * 2))); startY = patchSzOut - offsetY; endY = patchSzOut; } // end if if (range_x[col] == 0) startX = 0; // end if if (range_x[col] == width - patchSz) { startX = patchSzOut - offsetX; endX = patchSzOut; } // end if // Place patches for (int i = startY; i < endY; i++) { for (int j = startX; j < endX; j++) { cleanIm[range_y[row] + i, range_x[col] + j, k] = outputArray[i, j]; } // end for } //end } else { // All Inner Patches have outer edges cut off for (int i = step; i < patchSzOut - step; i++) { for (int j = step; j < patchSzOut - step; j++) { cleanIm[range_y[row] + i, range_x[col] + j, k] = outputArray[i, j]; } // end for } //end } #endregion #region Form elements if (cancelToken.IsCancellationRequested) cancelToken.ThrowIfCancellationRequested(); // Action when pause button is clicked await pauseToken.WaitWhilePausedAsync(); window.SetProgress1(1); #endregion } // end col for loop window.SetText2("Patches in " + Channels[k] + "row " + (row + 1) + " of " + range_y.Length + " done." + Environment.NewLine); } // end row for loop } return cleanIm; } // end method
/* -------------------------- Denoise by Patch ----------------------------------------------------------------- */ public async Task<byte[,,]> fdenoiseNeural(byte[,,] noisyIm, int step, string fileName, int layer, int[] networkSize, int[] inputsPerSample, int numberofsectors, CancellationToken cancelToken, PauseToken pauseToken) { /* noisyIm: an image corrupted by AWG noise the sliding window stride of the denoising process (a smaller stride will usually provide better results). The pixels of the clean image are assumed to be approximately in the range 0..255. */ #region Initialization window.SetText2("Initializing components...\r\n" + Environment.NewLine); // Appends the text to the console window window.SetProgress1(2); // Increments the progress bar by 2 window.SetText2("Loading weights... "); // load the weights Complex[][,] weights = loadMlmvnWeights(fileName, layer, networkSize, inputsPerSample); window.SetText2("Done." + Environment.NewLine); window.SetText2("Configuring patch size... "); // size of input / output patch int patchSz = (int)Math.Sqrt(weights[0].GetLength(1) - 1); // <-- Implement outside of function to determine type of weights int patchSzOut = (int)Math.Sqrt(weights[layer - 1].GetLength(0)); // Size of each sector on unit circle window.SetText2("Done.\r\n" + Environment.NewLine); window.SetText2("Input patch size is: " + patchSz + Environment.NewLine); window.SetText2("Output patch size is: " + patchSzOut + Environment.NewLine); // calculate the difference of the patches int p_diff = (patchSz - patchSzOut) / 2; // check if input is larger than output. If so, extend the image int height = noisyIm.GetLength(0); int origHeight = height; int width = noisyIm.GetLength(1); int origWidth = width; int samples = noisyIm.GetLength(2); if (p_diff > 0) { noisyIm = new byte[height + p_diff * 2, width + p_diff * 2, samples]; noisyIm = functions.MirrorImage(noisyIm, height, width, samples, p_diff); // if extended the image, update the size height = noisyIm.GetLength(0); width = noisyIm.GetLength(1); } #region Patch range configuration int pos = 0; // create arrays that contain the index ranges for row and column int[] range_y = new int[(height - patchSz) / step + 2]; int[] range_x = new int[(width - patchSz) / step + 2]; for (int i = 0; i < height - patchSz; i = i + step) { range_y[pos] = i; pos++; } // end for pos = 0; for (int i = 0; i < width - patchSz; i = i + step) { range_x[pos] = i; pos++; } // end for if (range_y[range_y.Length - 2] != height - patchSz) { range_y[range_y.Length - 1] = height - patchSz; } else Array.Resize(ref range_y, range_y.GetLength(0) - 1); // end if if (range_x[range_x.Length - 2] != height - patchSz) { range_x[range_x.Length - 1] = height - patchSz; } else Array.Resize(ref range_x, range_x.GetLength(0) - 1); // end if #endregion window.SetText2("\r\nDifference of the patche size is: " + p_diff + Environment.NewLine); window.SetText2("Beginning variable initialization... "); // pre-instantiate complex 2d-arrays // patch of interest int[,,] cleanIm = new int[origHeight, origWidth, samples]; byte[,,] counter = new byte[origHeight, origWidth, samples]; // counts the overlapped patch, then later store the processed image. double[,] inputArray = new double[patchSz, patchSz]; Complex[,] CinputArray = new Complex[patchSz, patchSz]; // output patch to be stored to actual image byte[,] outputArray = new byte[patchSz, patchSz]; byte[] output = new byte[(int)Math.Pow(patchSz, 2)]; // used when patch needs to be transformed to 1d array Complex[] S = new Complex[inputArray.Length]; // store outputs of network Complex[][] outputNeurons = new Complex[layer][]; double[] dOutputNeurons = new double[networkSize[layer - 1]]; // instanciate a jagged array to store outputs for (int i = 0; i < layer; i++) outputNeurons[i] = new Complex[networkSize[i]]; // end for Complex sum = new Complex(0, 0); S[0] = new Complex(1, 0); // instantiate imaginary unit Complex complex1 = new Complex(0.0, 1.0); // processIndex as in old code int offset = ((patchSzOut - 3) / 2) + 1; double bb = (2 * Math.PI) / numberofsectors; string[] Channels; switch (samples) { case 1: Channels = new string[] { "" }; break; case 3: Channels = new string[] { "red ", "green ", "blue " }; break; default: Channels = new string[] { "" }; break; } window.SetText2("Done.\r\n" + Environment.NewLine); window.SetText2("Beginning the processing... \r\n" + Environment.NewLine); #endregion //int increment = 0; //double test2 = range_x.GetLength(0)/2; //double test3 = Math.Floor(test2); // --------------- Processing Begins ------------------------------ // process each samples for (int k = 0; k < samples; k++) { for (int row = 0; row < range_y.GetLength(0); row++) // for each row { for (int col = 0; col < range_x.GetLength(0); col++) // for each column { #region process first layer // process first layer int ii = 0; byte[,] src = Functions.CreatePatch(noisyIm, range_y[row], range_x[col], k, patchSz); // upcast to double Array.Copy(src, inputArray, src.Length); // transformation of inputs into complex plane Inneficient? for (int i = 0; i < patchSz; i++) for (int j = 0; j < patchSz; j++) CinputArray[i, j] = Exp(complex1 * 2 * Math.PI * inputArray[i, j] / numberofsectors); // end nested for loop // transform to 1d array for (int i = 0; i < patchSz; i++) for (int j = 0; j < patchSz; j++) S[i * patchSz + j] = CinputArray[i, j]; // end for loop #endregion #region calculate weighted sum of first layer and its activation, line on MATLAB 1283 // calculate weighted sum & activation for (int i = 0; i < networkSize[0]; i++) { for (int j = 1; j < inputsPerSample[0]; j++) { sum = sum + weights[ii][i, j] * S[j - 1]; } sum = sum + weights[ii][i, 0]; outputNeurons[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply continuous activation for (int t = 0; t < networkSize[ii]; t++) outputNeurons[ii][t] /= Complex.Abs(outputNeurons[ii][t]); // end for #endregion #region calculate weighted sum of second to last layer // ----------------- Process second to last hidden layers, then output layer for (ii = 1; ii < layer - 1; ii++) { for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * outputNeurons[ii - 1][j - 1]; } sum = sum + weights[ii][i, 0]; outputNeurons[ii][i] = sum; sum = new Complex(0, 0); } // end for // apply contiunous activation for (int t = 0; t < networkSize[ii]; t++) outputNeurons[ii][t] /= Complex.Abs(outputNeurons[ii][t]); // end for } // end for ii // output layer ii = layer - 1; // set to last layer // calculate the weighted sum for (int i = 0; i < networkSize[ii]; i++) { for (int j = 1; j < inputsPerSample[ii]; j++) { sum = sum + weights[ii][i, j] * outputNeurons[ii - 1][j - 1]; } sum = sum + weights[ii][i, 0]; outputNeurons[ii][i] = sum; sum = new Complex(0, 0); } // end for for (int jj = 0; jj < networkSize[ii]; jj++) { // calculate discrete output // get angle dOutputNeurons[jj] = Math.Atan2(outputNeurons[ii][jj].Imaginary, outputNeurons[ii][jj].Real); if (dOutputNeurons[jj] < 0) dOutputNeurons[jj] = 2 * Math.PI + dOutputNeurons[jj]; // end if // round dOutputNeurons[jj] = Math.Truncate(dOutputNeurons[jj] / bb); //dOutputNeurons[jj] = Math.Floor(dOutputNeurons[jj]/bb); if (dOutputNeurons[jj] > 255) if (dOutputNeurons[jj] < 320) dOutputNeurons[jj] = 255; else dOutputNeurons[jj] = 0; // end if // convert results to byte output[jj] = Convert.ToByte(dOutputNeurons[jj]); //Trouble? } // end for #endregion second to last layer #region Process image // resize for (int i = 0; i < patchSzOut; i++) for (int j = 0; j < patchSzOut; j++) outputArray[i, j] = output[p_diff + j + (i * patchSz)]; // end for // add to the actual image for (int i = 0; i < patchSzOut; i++) for (int j = 0; j < patchSzOut; j++) { //if (counter[range_y[row] + i, range_x[col] + j] == 0) //{ cleanIm[range_y[row] + i, range_x[col] + j, k] += outputArray[i, j]; counter[range_y[row] + i, range_x[col] + j, k]++; //} } // end for // end for #endregion #region Form elements if (cancelToken.IsCancellationRequested) cancelToken.ThrowIfCancellationRequested(); // Action when pause button is clicked await pauseToken.WaitWhilePausedAsync(); window.SetProgress1(1); #endregion }//); // end col for loop window.SetText2("Patches in " + Channels[k] + "row " + (row + 1) + " of " + range_y.Length + " done." + Environment.NewLine); }//); // end row for loop } #region Average // Average for (int row = 0; row < origHeight; row++) // for each row { for (int col = 0; col < origWidth; col++) // for each column { for (int k = 0; k < samples; k++) // for each sample { cleanIm[row, col, k] /= counter[row, col, k]; counter[row, col, k] = Convert.ToByte(cleanIm[row, col, k]); } } } #endregion #region Old code //double[,] pixel_weights = new double[patchSzOut, patchSzOut]; //// median pixel ceiling(17/2) = 9 //int mid = (int)Math.Ceiling((double)patchSzOut/2); //// floor(17/2) / 2 = 4 //int sig = (int)Math.Floor((double)patchSzOut / 2) / weightSig; //// initialize pixel_weights //double d = 0; //for (int i = 0; i < patchSzOut; i++) // for (int j = 0; j < patchSzOut; j++) // { // d = Math.Sqrt(Math.Pow((i - mid),2) + Math.Pow((j - mid), 2)); // pixel_weights[i, j] = Math.Exp(Math.Pow(-d,2) / (2 * Math.Pow(sig, 2))) / (sig * Math.Sqrt(2 * Math.PI)); // } //// end for //// obtain the max of pixel_weights and subtract each element with it //// to achieve mean zero //double max = pixel_weights.Cast<double>().Max(); //for (int i = 0; i < patchSzOut; i++) // for (int j = 0; j < patchSzOut; j++) // pixel_weights[i, j] = pixel_weights[i, j] - max; //// end for //// Upcast byte to double //double[,] dnoisyIm = new double[noisyIm.GetLength(0), noisyIm.GetLength(1)]; //Array.Copy(noisyIm, dnoisyIm, noisyIm.Length); //// subract 0.5 and multiply by 0.2 to achieve approximately mean zero and //// variance close to one //for (int i = 0; i < dnoisyIm.GetLength(0); i++) // for (int j = 0; j < dnoisyIm.GetLength(1); j++ ) // dnoisyIm[i, j] = (((dnoisyIm[i, j] / 255) - 0.5) / 0.2); //// end for //int chunkSize = 1000; //int pos = 0; //// create arrays that contain the index ranges for row and column //int[] range_y = new int[(dnoisyIm.GetLength(0) - patchSz)/step + 2]; //int[] range_x = new int[(dnoisyIm.GetLength(1) - patchSz)/step + 2]; //for (int i = 0; i < noisyIm.GetLength(0) - patchSz; i = i + step) //{ // range_y[pos] = i; // pos++; //} //// end for //pos = 0; //for (int i = 0; i < noisyIm.GetLength(1) - patchSz; i = i + step) //{ // range_x[pos] = i; // pos++; //} //// end for //// if the ranges do not include the last available row / column, include them //if (range_y[range_y.GetLength(0) - 2] != noisyIm.GetLength(0) - patchSz) // range_y[range_y.GetLength(0) - 1] = noisyIm.GetLength(0) - patchSz; //else // Array.Resize(ref range_y, range_y.GetLength(0) - 1); //// end if //if (range_x[range_x.GetLength(0) - 2] != noisyIm.GetLength(1) - patchSz) // range_x[range_y.GetLength(0) - 1] = noisyIm.GetLength(1) - patchSz; //else // Array.Resize(ref range_x, range_x.GetLength(0) - 1); //// end if //double[,] res = new double[(int)Math.Pow(patchSz, 2), chunkSize]; //double[,] part = new double[(int)Math.Pow(patchSz, 2) + layer - 1, chunkSize]; //int[,] positions_out = new int[2, chunkSize]; //byte[,] denoisedIm = new byte[noisyIm.GetLength(0),noisyIm.GetLength(1)]; //Complex[,] wIm = new Complex[noisyIm.GetLength(0), noisyIm.GetLength(1)]; //byte[,] p = new byte[patchSz, patchSz]; //byte[] p1 = new byte[(int)Math.Pow(patchSz,2)]; // --------------------- Processing Image Begin --------------------------------------- //int idx = -1; //for (int y = 0; y < range_y.GetLength(0); y++) //{ // for (int x = 0; x < range_x.GetLength(0); x++) // { // // copy particular input patch from noisy image // for (int i = 0; i < patchSz; i++) // for (int j = 0; j < patchSz; j++) // p[i, j] = noisyIm[range_y[y] + i, range_x[x] + j]; // // end for // // increment index // idx++; // // convert p to 1d array // Buffer.BlockCopy(p,0, p1, 0, p1.Length * sizeof(byte)); // // copy whole patch as a row to the indexed row of res; // for (int i = 0; i < res.GetLength(0); i++) // res[i, idx] = p1[i]; // // end for // // copy the index of the particular iteration // positions_out[0, idx] = y; // positions_out[1, idx] = x; // // every time idx reaches 1000, below executes. after that, idx is reset to 0 // // ------------------------ Prediction -------------------------------------- // if ( idx >= chunkSize - 1 ) // { // // copy res to part // Array.Copy(res, part, res.Length); // for ( int i = 0; i<layer;i++) // { // for (int j = 0; j < part.GetLength(1);j++ ) // part[part.GetLength(0) - layer + 1, j] = 1; // // end for // } // end for // } // end if // } //} #endregion return counter; } // end method
/* -------------------------- Denoise by Pixels ----------------------------------------------------------------- */ public async Task<byte[,,]> Activation(byte[,,] noisyImage, int kernel, string weights, int numberofsectors, int inLayerSize, int hidLayerSize, CancellationToken cancelToken, PauseToken pauseToken) { // get height and width int height = noisyImage.GetLength(0); int width = noisyImage.GetLength(1); int samples = noisyImage.GetLength(2); int offset; switch (kernel) { case 3: offset = 1; break; case 5: offset = 2; break; case 7: offset = 3; break; default: offset = 0; break; } // end switch if (offset == 0) { window.SetText1("Value of kernel is not properly set." + Environment.NewLine); return null; } // extend the image byte[,,] image = new byte[height + offset * 2, width + offset * 2, samples]; image = functions.MirrorImage(noisyImage, height, width, samples, offset); window.SetProgress1(4); // pre-instantiate complex 2d-array double[,] inputArray = new double[kernel, kernel]; var CinputArray = new Complex[kernel, kernel]; // instantiate imaginary unit var complex1 = new Complex(0.0, 1.0); // pass to neural network byte[,] src; string[] Channels; switch (samples) { case 1: Channels = new string[] { "" }; break; case 3: Channels = new string[] { "red ", "green ", "blue " }; break; default: Channels = new string[] { "" }; break; } //int FirstQ = offset; //Parallel.For(FirstQ, height + offset, Q => for (int k = 0; k < samples; k++) { for (int Q = offset; Q < height + offset; Q++) { for (int P = offset; P < width + offset; P++) { src = Functions.CreateWindow(image, Q, P, k, kernel, offset); Array.Copy(src, inputArray, src.Length); // transformation of inputs into complex plane for (int i = 0; i < kernel; i++) { for (int j = 0; j < kernel; j++) CinputArray[i, j] = Exp(complex1 * 2 * Math.PI * inputArray[i, j] / numberofsectors); } // end nested for loop // process noisyImage[Q - offset, P - offset, k] = NeuralNetwork(CinputArray, weights, numberofsectors, inLayerSize, hidLayerSize); } // Action when cancel button is clicked if (cancelToken.IsCancellationRequested) cancelToken.ThrowIfCancellationRequested(); // Action when pause button is clicked await pauseToken.WaitWhilePausedAsync(); //Increments progress bar window.SetProgress1(1); // Writes progress to console if (Q % 10 == 0) window.SetText2("Pixels in " + Channels[k] + "row " + (Q) + " of " + height + " done." + Environment.NewLine); if (Q == height && Q % 10 != 0) window.SetText2("Pixels in " + Channels[k] + "row " + (Q) + " of " + height + " done." + Environment.NewLine); } };//); return noisyImage; }// end method