public static void SaveResultVideosLocally(List <SatyamResultsTableEntry> entries, string directoryName, int fps = 10) { directoryName = directoryName + "\\Raw"; if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); for (int i = 0; i < entries.Count; i++) { SatyamResultsTableEntry entry = entries[i]; SatyamResult satyamResult = JSonUtils.ConvertJSonToObject <SatyamResult>(entry.ResultString); SatyamTask task = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamResult.TaskParametersString); MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(task.jobEntry.JobParameters); //VATIC_DVA_CrowdsourcedResult taskr = new VATIC_DVA_CrowdsourcedResult(satyamResult.TaskResult, task.SatyamURI, start, end, task.SatyamJobSubmissionsTableEntryID.ToString()); VATIC_DVA_CrowdsourcedResult taskr = MultiObjectTrackingAggregator.createVATIC_DVA_CrowdsourcedResultUsingSatyamBlobImageCount(satyamResult.TaskResult, task.SatyamURI, entry.ID.ToString(), job.FrameRate); MultiObjectTrackingResult res = taskr.getCompressedTracksInTimeSegment(); List <string> ImageURLs = satyamStorage.getURLListOfSubDirectoryByURL(task.SatyamURI); string[] names = task.SatyamURI.Split('/'); string videoName = names[names.Length - 2] + "_" + entry.ID; generateVideoForEvaluation(ImageURLs, res, directoryName, videoName, job.FrameRate); } }
public static void SaveKITTIResultVideosLocally(List <SatyamResultsTableEntry> entries, string directoryName, int fps = 10) { directoryName = directoryName + "\\Raw"; if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); for (int i = 0; i < entries.Count; i++) { SatyamResultsTableEntry entry = entries[i]; SatyamResult satyamResult = JSonUtils.ConvertJSonToObject <SatyamResult>(entry.ResultString); SatyamTask task = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamResult.TaskParametersString); MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(task.jobEntry.JobParameters); //VATIC_DVA_CrowdsourcedResult taskr = VATIC_DVA_CrowdsourcedResult.createVATIC_DVA_CrowdsourcedResultUsingSatyamBlobImageCount(satyamResult.TaskResult, task.SatyamURI, task.SatyamJobSubmissionsTableEntryID.ToString(), job.FrameRate); //MultiObjectTrackingResult res = taskr.getCompressedTracksInTimeSegment(); string[] names = task.SatyamURI.Split('/'); string videoName = names[names.Length - 2] + "_" + entry.ID; string[] fields = videoName.Split('_'); string videoSequence = fields[fields.Length - 5]; int startingFrame = Convert.ToInt32(fields[fields.Length - 2]); int maxChunkEndFrame = startingFrame + job.ChunkDuration * job.FrameRate; int noFrameOverlap = (int)(job.ChunkOverlap * job.FrameRate); if (startingFrame != 0) { startingFrame -= noFrameOverlap; } if (entry.JobGUID == "1e43a983-548d-4a2e-8161-5537eb985902") { videoSequence = getCorrectSequenceNo(videoSequence); } string videoFrameDir = DirectoryConstants.KITTITrackingImages + videoSequence; List <string> files = Directory.GetFiles(videoFrameDir).ToList(); List <string> ImageURLs = new List <string>(); for (int j = startingFrame; j < files.Count && j < maxChunkEndFrame; j++) { ImageURLs.Add(files[j]); } if (ImageURLs.Count == 0) { continue; } VATIC_DVA_CrowdsourcedResult taskr = new VATIC_DVA_CrowdsourcedResult(satyamResult.TaskResult, videoName, entry.ID.ToString(), ImageURLs.Count, job.FrameRate); MultiObjectTrackingResult res = taskr.getCompressedTracksInTimeSegment(); generateVideoForEvaluation(ImageURLs, res, directoryName, videoName, job.FrameRate); } }
public static void SaveResultVideosLocally(List <SatyamResultsTableEntry> entries, string directoryName, int fps = 10) { directoryName = directoryName + "\\Raw"; if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); for (int i = 0; i < entries.Count; i++) { SatyamResultsTableEntry entry = entries[i]; SatyamResult satyamResult = JSonUtils.ConvertJSonToObject <SatyamResult>(entry.ResultString); SatyamTask task = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamResult.TaskParametersString); MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(task.jobEntry.JobParameters); string blobDir = URIUtilities.localDirectoryFullPathFromURI(task.SatyamURI); //VATIC_DVA_CrowdsourcedResult taskr = new VATIC_DVA_CrowdsourcedResult(satyamResult.TaskResult, task.SatyamURI, start, end, task.SatyamJobSubmissionsTableEntryID.ToString()); VATIC_DVA_CrowdsourcedResult taskr = MultiObjectTrackingAggregator.createVATIC_DVA_CrowdsourcedResultUsingSatyamBlobImageCount(satyamResult.TaskResult, blobDir, entry.ID.ToString(), job.FrameRate); MultiObjectTrackingResult res = taskr.getCompressedTracksInTimeSegment(); List <string> ImageURLs = satyamStorage.getURLListOfSpecificExtensionUnderSubDirectoryByURI(blobDir, new List <string>() { "jpg", "png" }); string videoName = URIUtilities.localDirectoryNameFromURI(blobDir) + "_" + URIUtilities.filenameFromURINoExtension(task.SatyamURI) + "_" + entry.ID; MultiObjectTrackingAnalyzer.generateVideoForEvaluation(ImageURLs, res, directoryName, videoName, job.FrameRate); } }
public static void SaveByGUIDSatyam(string guid) { //get all aggregated results SatyamAggregatedResultsTableAccess resultsDB = new SatyamAggregatedResultsTableAccess(); List <SatyamAggregatedResultsTableEntry> results = resultsDB.getEntriesByGUID(guid); resultsDB.close(); if (results.Count == 0) { return; } StringBuilder s = new StringBuilder(); for (int i = 0; i < results.Count; i++) { SatyamSaveAggregatedDataSatyam data = new SatyamSaveAggregatedDataSatyam(results[i]); String jsonString = JSonUtils.ConvertObjectToJSon <SatyamSaveAggregatedDataSatyam>(data); s.Append(jsonString); if (i == results.Count - 1) { s.Append("\n"); } } string dataToBeSaved = s.ToString(); SatyamJobStorageAccountAccess storage = new SatyamJobStorageAccountAccess(); string FileName = "AggregatedResults-" + results[0].JobGUID + ".txt"; string satyamDirectoryName = SatyamTaskGenerator.JobTemplateToSatyamContainerNameMap[results[0].JobTemplateType]; //switch(results[0].JobTemplateType) //{ // case TaskConstants.Classification_Image: // case TaskConstants.Classification_Image_MTurk: // satyamDirectoryName = "singleobjectlabeling"; // break; // case TaskConstants.Classification_Video: // case TaskConstants.Classification_Video_MTurk: // satyamDirectoryName = "singleobjectlabelinginvideo"; // break; // case TaskConstants.Counting_Image: // case TaskConstants.Counting_Image_MTurk: // satyamDirectoryName = "objectcounting"; // break; // case TaskConstants.Counting_Video: // case TaskConstants.Counting_Video_MTurk: // satyamDirectoryName = "objectcountinginvideo"; // break; // case TaskConstants.Detection_Image: // case TaskConstants.Detection_Image_MTurk: // satyamDirectoryName = "multiobjectlocalizationandlabeling"; // break; // case TaskConstants.Tracking: // case TaskConstants.Tracking_MTurk: // satyamDirectoryName = "multiobjecttracking"; // break; //} storage.SaveATextFile(satyamDirectoryName, results[0].JobGUID, FileName, dataToBeSaved); }
public static void SaveAggregatedResultVideosLocally(List <SatyamAggregatedResultsTableEntry> entries, string directoryName) { directoryName = directoryName + "\\Aggregated"; if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); for (int i = 0; i < entries.Count; i++) { SatyamAggregatedResultsTableEntry entry = entries[i]; SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(entry.ResultString); SatyamTask aggTask = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamAggResult.TaskParameters); MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(aggTask.jobEntry.JobParameters); MultiObjectTrackingAggregatedResult aggresult = JSonUtils.ConvertJSonToObject <MultiObjectTrackingAggregatedResult>(satyamAggResult.AggregatedResultString); List <string> ImageURLs = satyamStorage.getURLListOfSubDirectoryByURL(aggTask.SatyamURI); string videoName = URIUtilities.localDirectoryNameFromURI(aggTask.SatyamURI) + "_" + entry.ID; generateVideoForEvaluation(ImageURLs, aggresult.tracklets, directoryName, videoName, job.FrameRate); } }
public static void testGetURLListOfSubDirectoryByURL() { SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); string url = "https://satyamresearchjobstorage.blob.core.windows.net/multiobjecttracking/df2cedef-e707-4c32-b19e-c2599f9aaea3/Video_Bellevue_BellevueWay_NE8th_2016-10-13-8-2-30-000_2016-10-13-8-2-40-000_startingFrame_0/"; List <string> satyamURIList = satyamStorage.getURLListOfSubDirectoryByURL(url); foreach (string uri in satyamURIList) { Console.WriteLine(uri); } }
public static void testNonFlatListing() { SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); string satyamContainerName = "kittitracking"; string satyamDirectoryName = "all/Tracking_0000_153frame"; List <string> satyamURIList = satyamStorage.getURLList(satyamContainerName, satyamDirectoryName, false); foreach (string uri in satyamURIList) { Console.WriteLine(uri); } }
public static void GroupFramesIntoChunksAndUploadChunks(string videoName, string CurrentDir, int noFramePerChunk, int noFramesOverlap, string satyamContainerName, string satyamDirectoryName) { List <string> chunkFolders = GroupFramesIntoChunks(CurrentDir, noFramePerChunk, noFramesOverlap); SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); for (int i = 0; i < chunkFolders.Count; i++) { string subDir = chunkFolders[i]; satyamStorage.uploadALocalFolder(subDir, satyamContainerName, satyamDirectoryName + "/Video_" + videoName + "_startingFrame_" + noFramePerChunk * i); } }
public static void SaveKITTIAggregatedResultVideosLocally(List <SatyamAggregatedResultsTableEntry> entries, string directoryName) { directoryName = directoryName + "\\Aggregated"; if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); for (int i = 0; i < entries.Count; i++) { SatyamAggregatedResultsTableEntry entry = entries[i]; SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(entry.ResultString); SatyamTask aggTask = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamAggResult.TaskParameters); MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(aggTask.jobEntry.JobParameters); MultiObjectTrackingAggregatedResult aggresult = JSonUtils.ConvertJSonToObject <MultiObjectTrackingAggregatedResult>(satyamAggResult.AggregatedResultString); string[] names = aggTask.SatyamURI.Split('/'); string videoName = names[names.Length - 2] + "_" + entry.ID; string[] fields = videoName.Split('_'); string videoSequence = fields[fields.Length - 5]; int startingFrame = Convert.ToInt32(fields[fields.Length - 2]); int maxChunkEndFrame = startingFrame + job.ChunkDuration * job.FrameRate; int noFrameOverlap = (int)(job.ChunkOverlap * job.FrameRate); if (startingFrame != 0) { startingFrame -= noFrameOverlap; } if (entry.JobGUID == "1e43a983-548d-4a2e-8161-5537eb985902") { videoSequence = getCorrectSequenceNo(videoSequence); } string videoFrameDir = DirectoryConstants.KITTITrackingImages + videoSequence; List <string> files = Directory.GetFiles(videoFrameDir).ToList(); List <string> ImageURLs = new List <string>(); for (int j = startingFrame; j < files.Count && j < maxChunkEndFrame; j++) { ImageURLs.Add(files[j]); } generateVideoForEvaluation(ImageURLs, aggresult.tracklets, directoryName, videoName, job.FrameRate); } }
public static bool copyDataFromUserBlobToSatyamBlob(SatyamJobSubmissionsTableAccessEntry jobEntry) { string satyamContainerName = SatyamTaskGenerator.JobTemplateToSatyamContainerNameMap[jobEntry.JobTemplateType]; string GUID = jobEntry.JobGUID; string satyamDirectoryName = GUID; SatyamJob job = JSonUtils.ConvertJSonToObject <SatyamJob>(jobEntry.JobParametersString); BlobContainerManager bcm = new BlobContainerManager(); string status = bcm.Connect(job.azureInformation.AzureBlobStorageConnectionString); List <string> FileTypes = SatyamTaskGenerator.ValidFileTypesByTemplate[job.JobTemplateType]; if (status != "SUCCESS") { return(false); } SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); satyamStorage.copyFilesFromAnotherAzureBlob(bcm, job.azureInformation.AzureBlobStorageContainerName, job.azureInformation.AzureBlobStorageContainerDirectoryName, satyamContainerName, satyamDirectoryName, FileTypes); return(true); }
public static void SaveAggregatedResultVideosLocally(List <SatyamAggregatedResultsTableEntry> entries, string directoryName) { directoryName = directoryName + "\\Aggregated"; if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); for (int i = 0; i < entries.Count; i++) { SatyamAggregatedResultsTableEntry entry = entries[i]; SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(entry.ResultString); SatyamTask aggTask = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamAggResult.TaskParameters); MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(aggTask.jobEntry.JobParameters); TrackletLabelingAggregatedResult aggresult = JSonUtils.ConvertJSonToObject <TrackletLabelingAggregatedResult>(satyamAggResult.AggregatedResultString); WebClient wb = new WebClient(); Stream aggTrackStream = wb.OpenRead(aggresult.AggregatedTrackletsString_URL); StreamReader reader = new StreamReader(aggTrackStream); String aggTrackString = reader.ReadToEnd(); MultiObjectTrackingResult aggTracks = JSonUtils.ConvertJSonToObject <MultiObjectTrackingResult>(aggTrackString); string blobDir = URIUtilities.localDirectoryFullPathFromURI(aggTask.SatyamURI); List <string> ImageURLs = satyamStorage.getURLListOfSpecificExtensionUnderSubDirectoryByURI(blobDir, new List <string>() { "jpg", "png" }); string videoName = URIUtilities.localDirectoryNameFromURI(blobDir) + "_" + URIUtilities.filenameFromURINoExtension(aggTask.SatyamURI) + "_" + entry.ID; MultiObjectTrackingAnalyzer.generateVideoForEvaluation(ImageURLs, aggTracks, directoryName, videoName, job.FrameRate); } }
public static void SaveByGUIDSatyam(string guid) { //get all the results of a GUID SatyamResultsTableAccess resultsDB = new SatyamResultsTableAccess(); List <SatyamResultsTableEntry> results = resultsDB.getEntriesByGUID(guid); if (results.Count == 0) { resultsDB.close(); return; } //create the data to be saved List <SatyamResultSaveDataSatyam> savingDataList = new List <SatyamResultSaveDataSatyam>(); StringBuilder s = new StringBuilder(); for (int i = 0; i < results.Count; i++) { SatyamResultSaveDataSatyam data = new SatyamResultSaveDataSatyam(results[i]); String jsonString = JSonUtils.ConvertObjectToJSon(data); s.Append(jsonString); if (i == results.Count - 1) { s.Append("\n"); } } string dataToBeSaved = s.ToString(); SatyamJobStorageAccountAccess storage = new SatyamJobStorageAccountAccess(); string FileName = "Results-" + results[0].JobGUID + ".txt"; string satyamDirectoryName = SatyamTaskGenerator.JobTemplateToSatyamContainerNameMap[results[0].JobTemplateType]; storage.SaveATextFile(satyamDirectoryName, results[0].JobGUID, FileName, dataToBeSaved); resultsDB.close(); }
public static bool ProcessAndUploadToAzureBlob(SatyamJobSubmissionsTableAccessEntry jobEntry) { // Assumpltion: the input is a folder videos, convert to mp4, and upload to satyam blob SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); string satyamContainerName = SatyamTaskGenerator.JobTemplateToSatyamContainerNameMap[jobEntry.JobTemplateType]; string GUID = jobEntry.JobGUID; string satyamDirectoryName = GUID; SatyamJob job = JSonUtils.ConvertJSonToObject <SatyamJob>(jobEntry.JobParametersString); SingleObjectLabelingSubmittedJob jobParams = JSonUtils.ConvertJSonToObject <SingleObjectLabelingSubmittedJob>(job.JobParameters); BlobContainerManager bcm = new BlobContainerManager(); string status = bcm.Connect(job.azureInformation.AzureBlobStorageConnectionString); List <string> FileTypes = SatyamTaskGenerator.ValidFileTypesByTemplate[job.JobTemplateType]; if (status != "SUCCESS") { return(false); } string guidFolder = DirectoryConstants.defaultTempDirectory + "\\" + GUID; Directory.CreateDirectory(guidFolder); //var client = new WebClient(); List <string> videoUrls = bcm.getURLList(job.azureInformation.AzureBlobStorageContainerName, job.azureInformation.AzureBlobStorageContainerDirectoryName); foreach (string video in videoUrls) { FFMpegWrappers.ConvertVideoURLToMP4(DirectoryConstants.ffmpeg, video, guidFolder); } satyamStorage.uploadALocalFolder(guidFolder, satyamContainerName, satyamDirectoryName); return(true); }
private bool getNewRandomJob() { SatyamTaskTableAccess taskTableDB = new SatyamTaskTableAccess(); SatyamTaskTableEntry entry = taskTableDB.getMinimumTriedEntryByTemplate(TaskConstants.Tracking); if (entry != null) { taskTableDB.IncrementDoneScore(entry.ID); SatyamTask task = JSonUtils.ConvertJSonToObject <SatyamTask>(entry.TaskParametersString); SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); List <string> ImageURLs = satyamStorage.getURLListOfSubDirectoryByURL(task.SatyamURI); //string urls = ""; //for (int i=0;i<ImageURLs.Count;i++) //{ // urls += ImageURLs[i]; // if (i == ImageURLs.Count - 1) break; // urls += ','; //} Hidden_ImageURLList.Value = ObjectsToStrings.ListString(ImageURLs, ','); SatyamJob jobDefinitionEntry = task.jobEntry; MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(jobDefinitionEntry.JobParameters); Dictionary <string, List <string> > subcategories = job.Categories; List <string> categories = subcategories.Keys.ToList(); //CategorySelection_RakdioButtonList.Items.Clear(); for (int i = 0; i < categories.Count; i++) { ListItem l = new ListItem(categories[i]); //CategorySelection_RadioButtonList.Items.Add(l); } if (job.Description != "") { //DescriptionPanel.Visible = true; //DescriptionTextPanel.Controls.Add(new LiteralControl(job.Description)); } //Hidden_BoundaryLines.Value = JSonUtils.ConvertObjectToJSon(job.BoundaryLines); Hidden_TaskEntryString.Value = JSonUtils.ConvertObjectToJSon <SatyamTaskTableEntry>(entry); Hidden_PageLoadTime.Value = DateTime.Now.ToString(); // pass parameters from old template Slug_Hidden.Value = "null"; Start_Hidden.Value = "0"; Stop_Hidden.Value = (ImageURLs.Count - 1).ToString(); Skip_Hidden.Value = "0"; PerObject_Hidden.Value = "0.1"; Completion_Hidden.Value = "0.5"; BlowRadius_Hidden.Value = "0"; JobId_Hidden.Value = "1"; LabelString_Hidden.Value = ObjectsToStrings.ListString(categories.ToList(), ','); Attributes_Hidden.Value = ObjectsToStrings.DictionaryStringListString(subcategories, ',', ':', '_'); Training_Hidden.Value = "0"; fps_Hidden.Value = job.FrameRate.ToString(); Hidden_ChunkDuration.Value = job.ChunkDuration.ToString(); var web = new WebClient(); System.Drawing.Image x = System.Drawing.Image.FromStream(web.OpenRead(ImageURLs[0])); ImageWidth_Hidden.Value = x.Width.ToString(); ImageHeight_Hidden.Value = x.Height.ToString(); // image boundary for now //string[] region = new string[] { "0-0-1242-0-1242-375-0-375-0-0" }; string[] region = new string[] { "0-0-" + x.Width + "-0-" + x.Width + "-" + x.Height + "-0-" + x.Height + "-0-0" }; RegionString_Hidden.Value = ObjectsToStrings.ListString(region, ','); taskTableDB.close(); return(true); } else { taskTableDB.close(); return(false); } }
public static List <SatyamTask> generate(SatyamJobSubmissionsTableAccessEntry jobEntry) { SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); string satyamContainerName = JobTemplateToSatyamContainerNameMap[jobEntry.JobTemplateType]; string GUID = jobEntry.JobGUID; string satyamDirectoryName = GUID; SatyamJob job = JSonUtils.ConvertJSonToObject <SatyamJob>(jobEntry.JobParametersString); //BlobContainerManager bcm = new BlobContainerManager(); //string status = bcm.Connect(job.azureInformation.AzureBlobStorageConnectionString); //if (status != "SUCCESS") //{ // return null; //} ////first copy all the images to satyam location //List<string> FileTypes = ValidFileTypesByTemplate[job.JobTemplateType]; ////Now get all the URIs at the remote location that are relevant //List<string> FullURIList = bcm.getURLList(job.azureInformation.AzureBlobStorageContainerName, job.azureInformation.AzureBlobStorageContainerDirectoryName); //List<string> URIList = new List<string>(); //List<string> fileNameList = new List<string>(); //foreach(string uri in FullURIList) //{ // string filename = URIUtilities.filenameFromURI(uri); // if(CheckFileExtensions.IsAllowedType(filename,FileTypes)) // { // URIList.Add(uri); // fileNameList.Add(filename); // } //} ////Now create a dictionary mapping filename to URI for both the locations //Dictionary<string, string> fileNameToURI = new Dictionary<string, string>(); //for (int i = 0; i < URIList.Count; i++) //{ // string fileName = URIUtilities.filenameFromURI(URIList[i]); // fileNameToURI.Add(fileName, URIList[i]); //} List <string> satyamURIList = new List <string>(); switch (job.JobTemplateType) { case TaskConstants.Tracking: case TaskConstants.Tracking_MTurk: satyamURIList = satyamStorage.getImmediateNextLevelURLList(satyamContainerName, satyamDirectoryName); // list only immediate next level subblobs, directories / files break; case TaskConstants.TrackletLabeling: case TaskConstants.TrackletLabeling_MTurk: satyamURIList = satyamStorage.getURLListOfSpecificExtension(satyamContainerName, satyamDirectoryName, new List <string>() { "txt" }); // list only the annotation files per chunk per object break; case TaskConstants.Classification_Image: case TaskConstants.Classification_Image_MTurk: case TaskConstants.Classification_Video: case TaskConstants.Classification_Video_MTurk: case TaskConstants.Counting_Image: case TaskConstants.Counting_Image_MTurk: case TaskConstants.Counting_Video: case TaskConstants.Counting_Video_MTurk: case TaskConstants.Detection_Image: case TaskConstants.Detection_Image_MTurk: case TaskConstants.Segmentation_Image: case TaskConstants.Segmentation_Image_MTurk: case TaskConstants.OpenEndedQuestion_Image: case TaskConstants.OpenEndedQuestion_Image_MTurk: default: // all the images to satyam location satyamURIList = satyamStorage.getURLList(satyamContainerName, satyamDirectoryName); break; } //Dictionary<string, string> satyamFileNameToURI = new Dictionary<string, string>(); //for (int i = 0; i < satyamURIList.Count; i++) //{ // string satyamFileName = URIUtilities.filenameFromURI(satyamURIList[i]); // satyamFileNameToURI.Add(satyamFileName, satyamURIList[i]); //} //List<string> fileNameList = fileNameToURI.Keys.ToList(); //now create a task for each of these one by one List <SatyamTask> tasks = new List <SatyamTask>(); foreach (string uri in satyamURIList) { SatyamTask task = new SatyamTask(); task.jobEntry = job; //task.OriginalURI = fileNameToURI[filename]; task.SatyamURI = uri; tasks.Add(task); } return(tasks); }
public static ImageSegmentationAggregatedResult_NoHoles getAggregatedResult(List <ImageSegmentationResult_NoHoles> results, string SatyamURL, string guid, int MinResults = TaskConstants.IMAGE_SEGMENTATION_MTURK_MIN_RESULTS_TO_AGGREGATE, int MaxResults = TaskConstants.IMAGE_SEGMENTATION_MTURK_MAX_RESULTS_TO_AGGREGATE, double CategoryMajorityThreshold = TaskConstants.IMAGE_SEGMENTATION_MTURK_MAJORITY_CATEGORY_THRESHOLD, double PolygonBoundaryMajorityThreshold = TaskConstants.IMAGE_SEGMENTATION_MTURK_MAJORITY_POLYGON_BOUNDARY_THRESHOLD, double ObjectsCoverageThreshold = TaskConstants.IMAGE_SEGMENTATION_MTURK_OBJECT_COVERAGE_THRESHOLD_FOR_AGGREGATION_TERMINATION ) { if (results.Count < MinResults) //need at least three results! { return(null); } int ImageWidth = results[0].imageWidth; int ImageHeight = results[0].imageHeight; byte[] PNG = new byte[ImageHeight * ImageWidth]; ImageSegmentationAggregatedResult_NoHoles aggResult = new ImageSegmentationAggregatedResult_NoHoles(); aggResult.metaData = new ImageSegmentationAggregatedResultMetaData_NoHoles(); aggResult.metaData.TotalCount = results.Count; for (int i = 0; i < PNG.Length; i++) { PNG[i] = 0; } aggResult.boxesAndCategories = new ImageSegmentationResult_NoHoles(); aggResult.boxesAndCategories.objects = new List <ImageSegmentationResultSingleEntry_NoHoles>(); aggResult.boxesAndCategories.displayScaleReductionX = results[0].displayScaleReductionX; aggResult.boxesAndCategories.displayScaleReductionY = results[0].displayScaleReductionY; aggResult.boxesAndCategories.imageHeight = ImageHeight; aggResult.boxesAndCategories.imageWidth = ImageWidth; //first use multipartitie wieghted matching to associated the boxes disregarding the labels since //people might make mistake with lables but boxes are usually right List <List <GenericPolygon> > AllPolygons = new List <List <GenericPolygon> >(); List <int> noPolygonsPerResult = new List <int>(); foreach (ImageSegmentationResult_NoHoles res in results) { AllPolygons.Add(new List <GenericPolygon>()); if (res == null) { noPolygonsPerResult.Add(0); continue; } List <GenericPolygon> polygonList = AllPolygons[AllPolygons.Count - 1]; foreach (ImageSegmentationResultSingleEntry_NoHoles entry in res.objects) { polygonList.Add(entry.polygon); } noPolygonsPerResult.Add(polygonList.Count); } //now associate boxes across the various results List <MultipartiteWeightedMatch> polyAssociation = PolygonAssociation.computeGenericPolygonAssociations(AllPolygons); int noObjects = polyAssociation.Count; int noAssociatedPolygons = 0; //how many of the drawn boxes for each result were actually associated by two or more people for each user? SortedDictionary <int, int> noMultipleAssociatedPolygonsPerResult = new SortedDictionary <int, int>(); for (int i = 0; i < results.Count; i++) { noMultipleAssociatedPolygonsPerResult.Add(i, 0); } foreach (MultipartiteWeightedMatch match in polyAssociation) { if (match.elementList.Count > 1) //this has been corroborated by two people { noAssociatedPolygons++; foreach (KeyValuePair <int, int> entry in match.elementList) { noMultipleAssociatedPolygonsPerResult[entry.Key]++; } } } //count how many people have a high association ratio int noHighAssociationRatio = 0; for (int i = 0; i < results.Count; i++) { if (noPolygonsPerResult[i] == 0) { continue; } double ratio = (double)noMultipleAssociatedPolygonsPerResult[i] / (double)noPolygonsPerResult[i]; if (ratio > ObjectsCoverageThreshold) { noHighAssociationRatio++; } } if (noHighAssociationRatio < MinResults) //at least three people should have all their boxes highly corroborated by one other person { return(null); } //int noAcceptedPolygons = 0; for (int idx = 0; idx < polyAssociation.Count; idx++) { MultipartiteWeightedMatch match = polyAssociation[idx]; List <GenericPolygon> polyList = new List <GenericPolygon>(); List <string> identifiers = new List <string>(); foreach (KeyValuePair <int, int> entry in match.elementList) { polyList.Add(AllPolygons[entry.Key][entry.Value]); identifiers.Add(entry.Key + "_" + entry.Value); } //GenericPolygon aggregatedPolygon = GetAggregatedGenericPolygon_Relaxation(polyList, ImageWidth, ImageHeight, PolygonBoundaryMajorityThreshold); //GenericPolygon aggregatedPolygon = GetAggregatedGenericPolygon_MajorityEdge(polyList, ImageWidth, ImageHeight, PolygonBoundaryMajorityThreshold); GenericPolygon aggregatedPolygon = new GenericPolygon();// dummy polygon byte[] png = GetAggregatedGenericPolygon_PixelSweep(polyList, ImageWidth, ImageHeight, PolygonBoundaryMajorityThreshold); Dictionary <string, int> categoryNames = new Dictionary <string, int>(); int totalCount = match.elementList.Count; int maxCount = 0; string maxCategory = ""; foreach (KeyValuePair <int, int> entry in match.elementList) { string category = results[entry.Key].objects[entry.Value].Category; if (!categoryNames.ContainsKey(category)) { categoryNames.Add(category, 0); } categoryNames[category]++; if (maxCount < categoryNames[category]) { maxCount = categoryNames[category]; maxCategory = category; } } double probability = ((double)maxCount + 1) / ((double)totalCount + 2); if (probability < CategoryMajorityThreshold && results.Count < MaxResults) //this is not a valid category need more work { return(null); } // now we have one segment ready ImageSegmentationResultSingleEntry_NoHoles aggregated = new ImageSegmentationResultSingleEntry_NoHoles(); aggregated.polygon = aggregatedPolygon; aggregated.Category = maxCategory; aggResult.boxesAndCategories.objects.Add(aggregated); for (int i = 0; i < PNG.Length; i++) { if (PNG[i] == 0 && png[i] != 0) { PNG[i] = (byte)(idx + 1); } } } // save and upload to azure string filename = URIUtilities.filenameFromURINoExtension(SatyamURL); string filepath = DirectoryConstants.defaultTempDirectory + filename + "_aggregated.PNG"; ImageUtilities.savePNGRawData(filepath, ImageWidth, ImageHeight, PNG); SatyamJobStorageAccountAccess blob = new SatyamJobStorageAccountAccess(); string container = SatyamTaskGenerator.JobTemplateToSatyamContainerNameMap[TaskConstants.Segmentation_Image_MTurk]; string directoryPath = guid + "_aggregated"; blob.UploadALocalFile(filepath, container, directoryPath); aggResult.metaData.PNG_URL = TaskConstants.AzureBlobURL + container + "/" + directoryPath + "/" + filename + "_aggregated.PNG"; return(aggResult); }
public static MultiObjectTrackingResult stitchAllChunksOfOneVideo(List <SatyamAggregatedResultsTableEntry> entries, out List <string> ImageURLs, out int fps) { ImageURLs = new List <string>(); fps = 0; if (entries.Count == 0) { return(null); } SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); MultiObjectTrackingResult stitched = new MultiObjectTrackingResult(); int totalFrameCounts = 0; // ensure the order is correct SortedDictionary <int, SatyamAggregatedResultsTableEntry> sortedEntries = new SortedDictionary <int, SatyamAggregatedResultsTableEntry>(); List <int> idx = new List <int>(); for (int i = 0; i < entries.Count; i++) { SatyamAggregatedResultsTableEntry entry = entries[i]; SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(entry.ResultString); SatyamTask aggTask = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamAggResult.TaskParameters); string video = URIUtilities.localDirectoryNameFromURI(aggTask.SatyamURI); string[] fields = video.Split('_'); int startingFrame = Convert.ToInt32(fields[fields.Length - 1]); if (!sortedEntries.ContainsKey(startingFrame)) { sortedEntries.Add(startingFrame, entries[i]); idx.Add(startingFrame); } } idx.Sort(); for (int i = 0; i < idx.Count; i++) { //SatyamAggregatedResultsTableEntry entry = entries[i]; SatyamAggregatedResultsTableEntry entry = sortedEntries[idx[i]]; SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(entry.ResultString); SatyamTask aggTask = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamAggResult.TaskParameters); MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(aggTask.jobEntry.JobParameters); MultiObjectTrackingAggregatedResult aggresult = JSonUtils.ConvertJSonToObject <MultiObjectTrackingAggregatedResult>(satyamAggResult.AggregatedResultString); int noFramesOverlap = 0; if (job.ChunkOverlap != 0.0) { noFramesOverlap = (int)(job.ChunkOverlap * job.FrameRate); } List <string> TraceURLs = satyamStorage.getURLListOfSubDirectoryByURL(aggTask.SatyamURI); if (i == 0) { ImageURLs.AddRange(TraceURLs); string[] names = aggTask.SatyamURI.Split('/'); fps = job.FrameRate; stitched = aggresult.tracklets; totalFrameCounts += TraceURLs.Count; } else { int noNewFrames = 0; for (int j = noFramesOverlap; j < TraceURLs.Count; j++) { ImageURLs.Add(TraceURLs[j]); noNewFrames++; } //stitched = stitchTwoTracesByOneFrameBoundingBoxes(stitched, aggresult.tracklets, totalFrameCounts, totalFrameCounts+ noNewFrames, noFramesOverlap,fps); stitched = stitchTwoTracesByTubeletsOfOverlappingVideoChunk(stitched, aggresult.tracklets, totalFrameCounts, totalFrameCounts + noNewFrames, noFramesOverlap, fps); totalFrameCounts += noNewFrames; } //debug //generateVideoForEvaluation(ImageURLs, stitched, directoryName + "_" + i, videoName, fps); } return(stitched); }
/// <summary> /// Input should be a folder of videos and corresponding annotation file with the same name /// </summary> /// <param name="jobEntry"></param> public static bool ProcessAndUploadToAzureBlob(SatyamJobSubmissionsTableAccessEntry jobEntry) { // if the input is a folder of folders of frames, then copy directly SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); string satyamContainerName = SatyamTaskGenerator.JobTemplateToSatyamContainerNameMap[jobEntry.JobTemplateType]; string GUID = jobEntry.JobGUID; string satyamDirectoryName = GUID; SatyamJob job = JSonUtils.ConvertJSonToObject <SatyamJob>(jobEntry.JobParametersString); MultiObjectTrackingSubmittedJob jobParams = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(job.JobParameters); BlobContainerManager bcm = new BlobContainerManager(); string status = bcm.Connect(job.azureInformation.AzureBlobStorageConnectionString); List <string> FileTypes = SatyamTaskGenerator.ValidFileTypesByTemplate[job.JobTemplateType]; if (status != "SUCCESS") { return(false); } string guidFolder = DirectoryConstants.defaultTempDirectory + "\\" + GUID; Directory.CreateDirectory(guidFolder); int chunkLength = jobParams.ChunkDuration; // sec int outputFPS = jobParams.FrameRate; double chunkOverlap = jobParams.ChunkOverlap; // sec var client = new WebClient(); // sample to frames int noFramePerChunk = (int)(chunkLength * outputFPS); int noFrameOverlap = (int)(chunkOverlap * outputFPS); List <string> videoUrls = bcm.getURLList(job.azureInformation.AzureBlobStorageContainerName, job.azureInformation.AzureBlobStorageContainerDirectoryName); Dictionary <string, List <string> > videos = new Dictionary <string, List <string> >(); foreach (string videolink in videoUrls) { string videoName = URIUtilities.filenameFromURINoExtension(videolink); if (!videos.ContainsKey(videoName)) { videos.Add(videoName, new List <string>()); } videos[videoName].Add(videolink); } foreach (string videoName in videos.Keys) { // filter out those that doesn't provide a annotation file with it.... if (videos[videoName].Count != 2) { Console.WriteLine("Warning: Not 2 files provided for {0}.", videoName); //Directory.Delete(guidFolder, true); //return false; continue; } string videoURL = ""; string annotationURL = ""; foreach (string fileLink in videos[videoName]) { string extension = URIUtilities.fileExtensionFromURI(fileLink); if (extension != "txt") { videoURL = fileLink; } else { annotationURL = fileLink; } } string outputDirectory = guidFolder + "\\" + videoName; Directory.CreateDirectory(outputDirectory); string videoNameWithExtension = URIUtilities.filenameFromURI(videoURL); client.DownloadFile(videoURL, outputDirectory + "\\" + videoNameWithExtension); FFMpegWrappers.ExtractFrames(DirectoryConstants.ffmpeg, outputDirectory + "\\" + videoNameWithExtension, outputDirectory, videoName, DateTime.Now, outputFPS); File.Delete(outputDirectory + "\\" + videoNameWithExtension); List <string> chunkFolders = TrackingDataPreprocessor.GroupFramesIntoChunks(outputDirectory, noFramePerChunk); //parse VIRAT annotation file string annotationNameWithExtension = URIUtilities.filenameFromURI(annotationURL); client.DownloadFile(annotationURL, outputDirectory + "\\" + annotationNameWithExtension); parseAnnotationFileIntoChunkFolders(chunkFolders, outputDirectory + "\\" + annotationNameWithExtension, noFramePerChunk, outputFPS); //upload for (int i = 0; i < chunkFolders.Count; i++) { string subDir = chunkFolders[i]; satyamStorage.uploadALocalFolder(subDir, satyamContainerName, satyamDirectoryName + "/Video_" + videoName + "_startingFrame_" + noFramePerChunk * i); } Directory.Delete(outputDirectory, true); } return(true); }
private bool getNewRandomJob() { double price = 0; bool success = Double.TryParse(Hidden_Price.Value, out price); if (!success) { price = 0; } SatyamTaskTableAccess taskTableDB = new SatyamTaskTableAccess(); SatyamTaskTableEntry entry = null; if (Submit_Button.Enabled == true) { //entry = taskTableDB.getMinimumTriedNewEntryForWorkerIDByTemplateAndPrice(Hidden_AmazonWorkerID.Value, // TaskConstants.TrackletLabeling_MTurk, price); entry = taskTableDB.getTopKNewEntryForWorkerIDByTemplateAndPrice(50, Hidden_AmazonWorkerID.Value, TaskConstants.TrackletLabeling_MTurk, price); } else { entry = taskTableDB.getMinimumTriedEntryByTemplate(TaskConstants.TrackletLabeling_MTurk); } taskTableDB.close(); if (entry == null) { return(false); } taskTableDB = new SatyamTaskTableAccess(); taskTableDB.IncrementDoneScore(entry.ID); taskTableDB.close(); SatyamTask task = JSonUtils.ConvertJSonToObject <SatyamTask>(entry.TaskParametersString); SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); string videoDir = URIUtilities.localDirectoryFullPathFromURI(task.SatyamURI); List <string> ImageURLs = satyamStorage.getURLListOfSpecificExtensionUnderSubDirectoryByURI(videoDir, new List <string>() { "jpg" }); string annotationFilePath = task.SatyamURI; //string urls = ""; //for (int i=0;i<ImageURLs.Count;i++) //{ // urls += ImageURLs[i]; // if (i == ImageURLs.Count - 1) break; // urls += ','; //} Hidden_ImageURLList.Value = ObjectsToStrings.ListString(ImageURLs, ','); SatyamJob jobDefinitionEntry = task.jobEntry; MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(jobDefinitionEntry.JobParameters); Dictionary <string, List <string> > subcategories = job.Categories; List <string> categories = subcategories.Keys.ToList(); //CategorySelection_RakdioButtonList.Items.Clear(); for (int i = 0; i < categories.Count; i++) { ListItem l = new ListItem(categories[i]); //CategorySelection_RadioButtonList.Items.Add(l); } if (job.Description != "") { //DescriptionPanel.Visible = true; //DescriptionTextPanel.Controls.Add(new LiteralControl(job.Description)); } //Hidden_BoundaryLines.Value = JSonUtils.ConvertObjectToJSon(job.BoundaryLines); Hidden_TaskEntryString.Value = JSonUtils.ConvertObjectToJSon <SatyamTaskTableEntry>(entry); Hidden_PageLoadTime.Value = DateTime.Now.ToString(); // pass parameters from old template Slug_Hidden.Value = "null"; Start_Hidden.Value = "0"; Stop_Hidden.Value = (ImageURLs.Count - 1).ToString(); Skip_Hidden.Value = "0"; PerObject_Hidden.Value = "0.1"; Completion_Hidden.Value = "0.5"; BlowRadius_Hidden.Value = "0"; JobId_Hidden.Value = "1"; LabelString_Hidden.Value = ObjectsToStrings.ListString(categories.ToList(), ','); Attributes_Hidden.Value = ObjectsToStrings.DictionaryStringListString(subcategories, ',', ':', '_'); Training_Hidden.Value = "0"; fps_Hidden.Value = job.FrameRate.ToString(); Hidden_ChunkDuration.Value = job.ChunkDuration.ToString(); var web = new WebClient(); System.Drawing.Image x = System.Drawing.Image.FromStream(web.OpenRead(ImageURLs[0])); ImageWidth_Hidden.Value = x.Width.ToString(); ImageHeight_Hidden.Value = x.Height.ToString(); // image boundary for now //string[] region = new string[] { "0-0-1242-0-1242-375-0-375-0-0" }; string[] region = new string[] { "0-0-" + x.Width + "-0-" + x.Width + "-" + x.Height + "-0-" + x.Height + "-0-0" }; RegionString_Hidden.Value = ObjectsToStrings.ListString(region, ','); // temp test List <VATIC_Tracklet> prevTracesTemp = new List <VATIC_Tracklet>(); WebClient client = new WebClient(); Stream stream = client.OpenRead(annotationFilePath); StreamReader reader = new StreamReader(stream); List <string> trace = new List <string>(); while (reader.Peek() >= 0) { string content = reader.ReadLine(); trace.Add(content); } Dictionary <string, VATIC_Tracklet> tracklets = VATIC_Tracklet.ReadTrackletsFromVIRAT(trace); foreach (string id in tracklets.Keys) { //string output = JSonUtils.ConvertObjectToJSon(tracklets[id]); prevTracesTemp.Add(tracklets[id]); } string output = JSonUtils.ConvertObjectToJSon(prevTracesTemp); PreviousTrackString_Hidden.Value = output; return(true); }
public static void ValidateSatyamImageNetClassificationAggregationResultByGUID(string guid, string confusingImageListFilePath = null, bool prepareDataForTraining = false, string outputDirectory = null) { Dictionary <string, ConfusingReason> imageBlackListReason = new Dictionary <string, ConfusingReason>(); if (confusingImageListFilePath != null) { imageBlackListReason = getConfusingImageList(confusingImageListFilePath); } //get all aggregated results SatyamAggregatedResultsTableAccess resultsDB = new SatyamAggregatedResultsTableAccess(); List <SatyamAggregatedResultsTableEntry> results = resultsDB.getEntriesByGUID(guid); resultsDB.close(); int noTotal = 0; int noCorrect = 0; SortedDictionary <string, Dictionary <string, int> > confusionMatrix_res_groundtruth = new SortedDictionary <string, Dictionary <string, int> >(); SortedDictionary <string, Dictionary <string, int> > confusionMatrix_groundtruth_res = new SortedDictionary <string, Dictionary <string, int> >(); StringBuilder s = new StringBuilder(); s.Append("<!DOCTYPE html>\n"); s.Append("<html>\n"); s.Append("<body>\n"); String title = String.Format("<h1>Job GUID {0} Incorrect Result Summary</h1>\n", guid); s.Append(title); WebClient wc = new WebClient(); for (int i = 0; i < results.Count; i++) { SatyamSaveAggregatedDataSatyam data = new SatyamSaveAggregatedDataSatyam(results[i]); //String uri = data.SatyamURI; //string[] uri_parts= uri.Split('/'); //string[] name_parts = uri_parts[uri_parts.Length - 1].Split('_'); string fileName = URIUtilities.filenameFromURI(data.SatyamURI); string imageCategoryName = fileName.Split('_')[0]; String resultString = data.AggregatedResultString; SingleObjectLabelingAggregatedResult result = JSonUtils.ConvertJSonToObject <SingleObjectLabelingAggregatedResult>(resultString); // skip all ambulances and black listed if (IsBlackListed(data.SatyamURI, imageBlackListReason)) { continue; } if (!confusionMatrix_res_groundtruth.ContainsKey(result.Category)) { confusionMatrix_res_groundtruth.Add(result.Category, new Dictionary <string, int>() { { GroundTruth[imageCategoryName], 0 } }); } else { if (!confusionMatrix_res_groundtruth[result.Category].ContainsKey(GroundTruth[imageCategoryName])) { confusionMatrix_res_groundtruth[result.Category].Add(GroundTruth[imageCategoryName], 0); } } if (!confusionMatrix_groundtruth_res.ContainsKey(GroundTruth[imageCategoryName])) { confusionMatrix_groundtruth_res.Add(GroundTruth[imageCategoryName], new Dictionary <string, int>() { { result.Category, 0 } }); } else { if (!confusionMatrix_groundtruth_res[GroundTruth[imageCategoryName]].ContainsKey(result.Category)) { confusionMatrix_groundtruth_res[GroundTruth[imageCategoryName]].Add(result.Category, 0); } } if (result.Category.Equals(GroundTruth[imageCategoryName], StringComparison.InvariantCultureIgnoreCase)) { noCorrect++; } else { //Console.WriteLine("{0}, Groundtruth: {1}, Aggregated: {2}, Votes: {3}", // fileName, GroundTruth[imageCategoryName], result.Category, // JSonUtils.ConvertObjectToJSon(result.metaData)); String record = String.Format("<p>{0}, Groundtruth: {1}, Aggregated: {2}, Votes: {3}</p>\n", fileName, GroundTruth[imageCategoryName], result.Category, JSonUtils.ConvertObjectToJSon(result.metaData)); String img = String.Format("<img src=\"{0}\" >\n", data.SatyamURI); s.Append(record); s.Append(img); } // prepare training dataset if (prepareDataForTraining) { if (GroundTruth[imageCategoryName] != "ambulance" && result.Category != "ambulance") { Image im = Image.FromStream(wc.OpenRead(data.SatyamURI)); if (!Directory.Exists(outputDirectory + result.Category)) { Directory.CreateDirectory(outputDirectory + result.Category); } im.Save(outputDirectory + "\\" + result.Category + "\\" + fileName); } } noTotal++; confusionMatrix_res_groundtruth[result.Category][GroundTruth[imageCategoryName]]++; confusionMatrix_groundtruth_res[GroundTruth[imageCategoryName]][result.Category]++; } Console.WriteLine("Result: {0}/{1}, precision: {2}", noCorrect, noTotal, (double)noCorrect / noTotal); // write the confusion matrix s.Append("<p>"); String row = "\t\t"; foreach (string resultCategory in confusionMatrix_res_groundtruth.Keys) { row += resultCategory + "\t"; } row += "<br>\n"; s.Append(row); Console.WriteLine(row); foreach (string groundTruthCategory in confusionMatrix_groundtruth_res.Keys) { row = groundTruthCategory + "\t"; foreach (string resultCategory in confusionMatrix_res_groundtruth.Keys) { if (confusionMatrix_groundtruth_res[groundTruthCategory].ContainsKey(resultCategory)) { row += confusionMatrix_groundtruth_res[groundTruthCategory][resultCategory].ToString(); } else { row += "0"; } row += "\t"; } row += "<br>\n"; s.Append(row); Console.WriteLine(row); } s.Append("</p>\n"); s.Append("</body>\n"); s.Append("</html>\n"); string dataToBeSaved = s.ToString(); SatyamJobStorageAccountAccess storage = new SatyamJobStorageAccountAccess(); string FileName = "AggregatedIncorrectResults-" + guid + ".html"; storage.SaveATextFile("singleobjectlabeling", guid, FileName, dataToBeSaved); }
public static void AggregateWithParameterAndValidateSatyamImageNetClassificationResultByGUID(string guid, int MinResults = TaskConstants.SINGLE_OBJECT_LABLING_MTURK_MIN_RESULTS_TO_AGGREGATE, int MaxResults = TaskConstants.SINGLE_OBJECT_LABLING_MTURK_MAX_RESULTS_TO_AGGREGATE, double MajorityThreshold = TaskConstants.SINGLE_OBJECT_LABLING_MTURK_MAJORITY_THRESHOLD, string confusingImageListFilePath = null) { string configString = "Min_" + MinResults + "_Max_" + MaxResults + "_Thresh_" + MajorityThreshold; Console.WriteLine("Aggregating for param set " + configString); int noTerminatedTasks = 0; SatyamResultsTableAccess resultsDB = new SatyamResultsTableAccess(); List <SatyamResultsTableEntry> entries = resultsDB.getEntriesByGUIDOrderByID(guid); resultsDB.close(); //SortedDictionary<DateTime, List<SatyamResultsTableEntry>> entriesBySubmitTime = // SatyamResultValidation.SortResultsBySubmitTime_OneResultPerTurkerPerTask(entries); SortedDictionary <DateTime, List <SatyamResultsTableEntry> > entriesBySubmitTime = SatyamResultValidationToolKit.SortResultsBySubmitTime(entries); Dictionary <string, ConfusingReason> imageBlackListReason = new Dictionary <string, ConfusingReason>(); if (confusingImageListFilePath != null) { imageBlackListReason = getConfusingImageList(confusingImageListFilePath); } //Dictionary<int, List<SingleObjectLabelingResult>> ResultsPerTask = new Dictionary<int, List<SingleObjectLabelingResult>>(); Dictionary <int, List <SatyamResultsTableEntry> > ResultsPerTask = new Dictionary <int, List <SatyamResultsTableEntry> >(); List <int> aggregatedTasks = new List <int>(); int noTotalConverged = 0; int noCorrect = 0; SortedDictionary <string, Dictionary <string, int> > confusionMatrix_res_groundtruth = new SortedDictionary <string, Dictionary <string, int> >(); SortedDictionary <string, Dictionary <string, int> > confusionMatrix_groundtruth_res = new SortedDictionary <string, Dictionary <string, int> >(); StringBuilder s = new StringBuilder(); s.Append("<!DOCTYPE html>\n"); s.Append("<html>\n"); s.Append("<body>\n"); String title = String.Format("<h1>Job GUID {0} Incorrect Result Summary</h1>\n", guid); s.Append(title); Dictionary <int, int> noResultsNeededForAggregation = SatyamResultsAnalysis.getNoResultsNeededForAggregationFromLog(configString, guid); Dictionary <int, int> noResultsNeededForAggregation_new = new Dictionary <int, int>(); List <SatyamAggregatedResultsTableEntry> aggEntries = new List <SatyamAggregatedResultsTableEntry>(); foreach (DateTime t in entriesBySubmitTime.Keys) { foreach (SatyamResultsTableEntry entry in entriesBySubmitTime[t]) { //SatyamResultsTableEntry entry = entries[i]; SatyamResult satyamResult = JSonUtils.ConvertJSonToObject <SatyamResult>(entry.ResultString); SatyamTask task = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamResult.TaskParametersString); SatyamJob job = task.jobEntry; string fileName = URIUtilities.filenameFromURI(task.SatyamURI); string imageCategoryName = fileName.Split('_')[0]; if (IsBlackListed(task.SatyamURI, imageBlackListReason)) { continue; } int taskEntryID = entry.SatyamTaskTableEntryID; if (aggregatedTasks.Contains(taskEntryID)) { continue; } if (!ResultsPerTask.ContainsKey(taskEntryID)) { ResultsPerTask.Add(taskEntryID, new List <SatyamResultsTableEntry>()); } //ResultEntriesPerTask[taskEntryID].Add(JSonUtils.ConvertJSonToObject<SingleObjectLabelingResult>(satyamResult.TaskResult)); ResultsPerTask[taskEntryID].Add(entry); // check log if enough results are collected if (noResultsNeededForAggregation != null && noResultsNeededForAggregation.ContainsKey(taskEntryID) && ResultsPerTask[taskEntryID].Count < noResultsNeededForAggregation[taskEntryID]) { continue; } string aggResultString = SingleObjectLabelingAggregator.GetAggregatedResultString(ResultsPerTask[taskEntryID], MinResults, MaxResults, MajorityThreshold); //SingleObjectLabelingAggregatedResult aggResult = SingleObjectLabelingAggregator.getAggregatedResult(ResultEntriesPerTask[taskEntryID], MinResults, MaxResults, MajorityThreshold); if (aggResultString == null) { continue; } SatyamAggregatedResultsTableEntry aggEntry = new SatyamAggregatedResultsTableEntry(); aggEntry.JobGUID = ResultsPerTask[taskEntryID][0].JobGUID; aggEntry.JobTemplateType = ResultsPerTask[taskEntryID][0].JobTemplateType; aggEntry.SatyamTaskTableEntryID = ResultsPerTask[taskEntryID][0].SatyamTaskTableEntryID; aggEntry.UserID = ResultsPerTask[taskEntryID][0].UserID; aggEntry.ResultString = aggResultString; /// aggregation happen // record logs if (noResultsNeededForAggregation == null || !noResultsNeededForAggregation.ContainsKey(taskEntryID)) { noResultsNeededForAggregation_new.Add(taskEntryID, ResultsPerTask[taskEntryID].Count); } /// //if (aggResult.Category == "None of the Above") //{ // continue; //} aggEntries.Add(aggEntry); SatyamSaveAggregatedDataSatyam data = new SatyamSaveAggregatedDataSatyam(aggEntry); String resultString = data.AggregatedResultString; SingleObjectLabelingAggregatedResult aggResult = JSonUtils.ConvertJSonToObject <SingleObjectLabelingAggregatedResult>(resultString); if (!confusionMatrix_res_groundtruth.ContainsKey(aggResult.Category)) { confusionMatrix_res_groundtruth.Add(aggResult.Category, new Dictionary <string, int>() { { GroundTruth[imageCategoryName], 0 } }); } else { if (!confusionMatrix_res_groundtruth[aggResult.Category].ContainsKey(GroundTruth[imageCategoryName])) { confusionMatrix_res_groundtruth[aggResult.Category].Add(GroundTruth[imageCategoryName], 0); } } if (!confusionMatrix_groundtruth_res.ContainsKey(GroundTruth[imageCategoryName])) { confusionMatrix_groundtruth_res.Add(GroundTruth[imageCategoryName], new Dictionary <string, int>() { { aggResult.Category, 0 } }); } else { if (!confusionMatrix_groundtruth_res[GroundTruth[imageCategoryName]].ContainsKey(aggResult.Category)) { confusionMatrix_groundtruth_res[GroundTruth[imageCategoryName]].Add(aggResult.Category, 0); } } if (aggResult.Category.Equals(GroundTruth[imageCategoryName], StringComparison.InvariantCultureIgnoreCase)) { noCorrect++; } else { //Console.WriteLine("{0}, Groundtruth: {1}, Aggregated: {2}, Votes: {3}", // fileName, GroundTruth[imageCategoryName], aggResult.Category, // JSonUtils.ConvertObjectToJSon(aggResult.metaData)); String record = String.Format("<p>{0}, Groundtruth: {1}, Aggregated: {2}, Votes: {3}</p>\n", fileName, GroundTruth[imageCategoryName], aggResult.Category, JSonUtils.ConvertObjectToJSon(aggResult.metaData)); String img = String.Format("<img src=\"{0}\" >\n", task.SatyamURI); s.Append(record); s.Append(img); } noTotalConverged++; if (ResultsPerTask[taskEntryID].Count >= MaxResults) { noTerminatedTasks++; } confusionMatrix_res_groundtruth[aggResult.Category][GroundTruth[imageCategoryName]]++; confusionMatrix_groundtruth_res[GroundTruth[imageCategoryName]][aggResult.Category]++; aggregatedTasks.Add(taskEntryID); } } SatyamResultsAnalysis.RecordAggregationLog(noResultsNeededForAggregation_new, configString, guid); s.Append("</body>\n"); s.Append("</html>\n"); string dataToBeSaved = s.ToString(); SatyamJobStorageAccountAccess storage = new SatyamJobStorageAccountAccess(); string FileName = String.Format("AggregatedIncorrectResults-{0}_Min{1}Max{2}Thresh{3}.html", guid, MinResults, MaxResults, MajorityThreshold); storage.SaveATextFile("singleobjectlabeling", guid, FileName, dataToBeSaved); s.Clear(); s.Append("<!DOCTYPE html>\n"); s.Append("<html>\n"); s.Append("<body>\n"); s.Append(title); string resultSummary = String.Format("<p>Result: {0}/{1}, precision: {2}</p>\n", noCorrect, noTotalConverged, (double)noCorrect / noTotalConverged); resultSummary += String.Format("<p>Terminated: {0}, Not Enough Results: {1}</p>\n", noTerminatedTasks, ResultsPerTask.Count - noTotalConverged); Console.WriteLine(resultSummary); s.Append(resultSummary); // write the confusion matrix s.Append("<p>"); String row = "\t\t"; foreach (string resultCategory in confusionMatrix_res_groundtruth.Keys) { row += resultCategory + "\t"; } row += "<br>\n"; s.Append(row); Console.WriteLine(row); string matString = ""; foreach (string groundTruthCategory in confusionMatrix_groundtruth_res.Keys) { row = groundTruthCategory + "\t"; foreach (string resultCategory in confusionMatrix_res_groundtruth.Keys) { if (confusionMatrix_groundtruth_res[groundTruthCategory].ContainsKey(resultCategory)) { row += confusionMatrix_groundtruth_res[groundTruthCategory][resultCategory].ToString(); } else { row += "0"; } row += "\t"; } row += "<br>\n"; s.Append(row); Console.WriteLine(row); matString += row; } s.Append("</p>\n"); s.Append("</body>\n"); s.Append("</html>\n"); string summaryToBeSaved = s.ToString(); FileName = String.Format("Aggregated_Summary-{0}_Min{1}Max{2}Thresh{3}.html", guid, MinResults, MaxResults, MajorityThreshold); storage.SaveATextFile("singleobjectlabeling", guid, FileName, summaryToBeSaved); /// local file string outputString = String.Format("{0} {1} {2} {3} {4} {5}\n", configString, noCorrect, noTotalConverged, (double)noCorrect / noTotalConverged, noTerminatedTasks, ResultsPerTask.Count - noTotalConverged); string outputfile = DirectoryConstants.defaultTempDirectory + guid + "\\resultSummary.txt"; File.AppendAllText(outputfile, outputString); string outputmatFile = DirectoryConstants.defaultTempDirectory + guid + "\\" + configString + "_mat.txt"; File.WriteAllText(outputmatFile, matString); //for (double prob = 0; prob < 1;prob +=0.2) //{ // SatyamResultsAnalysis.AnalyzeApprovalRate(aggEntries, entries, guid, configString, anotherChanceProbablity: prob); //} //for (double ratio = 0; ratio < 1; ratio += 0.2) //{ // SatyamResultsAnalysis.AnalyzeApprovalRate(aggEntries, entriesBySubmitTime, noResultsNeededForAggregation, noResultsNeededForAggregation_new, guid, configString, approvalRatioThreshold: ratio); //} SatyamResultsAnalysis.AggregationAnalysis(aggEntries, entriesBySubmitTime, noResultsNeededForAggregation, noResultsNeededForAggregation_new, guid, configString); }
public static MultiObjectTrackingResult stitchAllChunksAllObjectsOfOneVideo(List <SatyamAggregatedResultsTableEntry> entries, out List <string> ImageURLs, out int fps) { ImageURLs = new List <string>(); fps = 0; if (entries.Count == 0) { return(null); } SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); MultiObjectTrackingResult stitched = new MultiObjectTrackingResult(); int totalFrameCounts = 0; // ensure the order is correct SortedDictionary <int, List <SatyamAggregatedResultsTableEntry> > sortedEntries = new SortedDictionary <int, List <SatyamAggregatedResultsTableEntry> >(); List <int> idx = new List <int>(); for (int i = 0; i < entries.Count; i++) { SatyamAggregatedResultsTableEntry entry = entries[i]; SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(entry.ResultString); SatyamTask aggTask = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamAggResult.TaskParameters); string video = URIUtilities.localDirectoryNameFromURI(aggTask.SatyamURI); string[] fields = video.Split('_'); int startingFrame = Convert.ToInt32(fields[fields.Length - 1]); if (!sortedEntries.ContainsKey(startingFrame)) { sortedEntries.Add(startingFrame, new List <SatyamAggregatedResultsTableEntry>()); idx.Add(startingFrame); } sortedEntries[startingFrame].Add(entries[i]); } idx.Sort(); List <string> AggObjIds = new List <string>(); for (int i = 0; i < idx.Count; i++) { int noFramesOverlap = 0; string blobDir = ""; // grouping all objects that belong to the same chunk MultiObjectTrackingResult aggTracksOfAllObjectsPerChunk = new MultiObjectTrackingResult(); List <string> objIds = new List <string>(); for (int j = 0; j < sortedEntries[idx[i]].Count; j++) { SatyamAggregatedResultsTableEntry entry = sortedEntries[idx[i]][j]; SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(entry.ResultString); SatyamTask aggTask = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamAggResult.TaskParameters); MultiObjectTrackingSubmittedJob job = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(aggTask.jobEntry.JobParameters); if (job.ChunkOverlap != 0.0) { noFramesOverlap = (int)(job.ChunkOverlap * job.FrameRate); } fps = job.FrameRate; blobDir = URIUtilities.localDirectoryFullPathFromURI(aggTask.SatyamURI); string objId = URIUtilities.filenameFromURINoExtension(aggTask.SatyamURI); objIds.Add(objId); TrackletLabelingAggregatedResult aggresult = JSonUtils.ConvertJSonToObject <TrackletLabelingAggregatedResult>(satyamAggResult.AggregatedResultString); WebClient wb = new WebClient(); Stream aggTrackStream = wb.OpenRead(aggresult.AggregatedTrackletsString_URL); StreamReader reader = new StreamReader(aggTrackStream); String aggTrackString = reader.ReadToEnd(); MultiObjectTrackingResult aggTracks = JSonUtils.ConvertJSonToObject <MultiObjectTrackingResult>(aggTrackString); if (aggTracksOfAllObjectsPerChunk.tracks.Count == 0) { aggTracksOfAllObjectsPerChunk = aggTracks; } else { for (int k = 0; k < aggTracks.tracks.Count; k++) { aggTracksOfAllObjectsPerChunk.tracks.Add(aggTracks.tracks[k]); } } } List <string> TraceURLs = satyamStorage.getURLListOfSpecificExtensionUnderSubDirectoryByURI(blobDir, new List <string>() { "jpg", "png" }); if (i == 0) { ImageURLs.AddRange(TraceURLs); stitched = aggTracksOfAllObjectsPerChunk; totalFrameCounts += TraceURLs.Count; AggObjIds = objIds; } else { int noNewFrames = 0; for (int j = noFramesOverlap; j < TraceURLs.Count; j++) { ImageURLs.Add(TraceURLs[j]); noNewFrames++; } //stitched = MultiObjectTrackingAnalyzer.stitchTwoTracesByTubeletsOfOverlappingVideoChunk(stitched, // aggTracksOfAllObjectsPerChunk, totalFrameCounts, totalFrameCounts + noNewFrames, noFramesOverlap, fps); // postpone the agg trace double frameTimeInMiliSeconds = (double)1000 / (double)fps; double timeToPostponeInMilliSeconds = (double)(totalFrameCounts - noFramesOverlap) * frameTimeInMiliSeconds; //TimeSpan timeSpanToPostponeInSeconds = new TimeSpan(0,0,0,0, (int)timeToPostponeInMilliSeconds); TimeSpan timeSpanToPostponeInSeconds = DateTimeUtilities.getTimeSpanFromTotalMilliSeconds((int)timeToPostponeInMilliSeconds); aggTracksOfAllObjectsPerChunk.postpone(timeSpanToPostponeInSeconds); // overlap must be 0 for (int k = 0; k < aggTracksOfAllObjectsPerChunk.tracks.Count; k++) { if (!AggObjIds.Contains(objIds[k])) { stitched.tracks.Add(aggTracksOfAllObjectsPerChunk.tracks[k]); AggObjIds.Add(objIds[k]); } else { // stitch the track for the same id int tckIdx = AggObjIds.IndexOf(objIds[k]); stitched.tracks[tckIdx] = CompressedTrack.stitchTwoAdjacentTrack(stitched.tracks[tckIdx], aggTracksOfAllObjectsPerChunk.tracks[k]); } } totalFrameCounts += noNewFrames; } //debug //generateVideoForEvaluation(ImageURLs, stitched, directoryName + "_" + i, videoName, fps); } return(stitched); }
public static bool ProcessAndUploadToAzureBlob(SatyamJobSubmissionsTableAccessEntry jobEntry) { // if the input is a folder of folders of frames, then copy directly SatyamJobStorageAccountAccess satyamStorage = new SatyamJobStorageAccountAccess(); string satyamContainerName = SatyamTaskGenerator.JobTemplateToSatyamContainerNameMap[jobEntry.JobTemplateType]; string GUID = jobEntry.JobGUID; string satyamDirectoryName = GUID; SatyamJob job = JSonUtils.ConvertJSonToObject <SatyamJob>(jobEntry.JobParametersString); MultiObjectTrackingSubmittedJob jobParams = JSonUtils.ConvertJSonToObject <MultiObjectTrackingSubmittedJob>(job.JobParameters); BlobContainerManager bcm = new BlobContainerManager(); string status = bcm.Connect(job.azureInformation.AzureBlobStorageConnectionString); List <string> FileTypes = SatyamTaskGenerator.ValidFileTypesByTemplate[job.JobTemplateType]; if (status != "SUCCESS") { return(false); } string guidFolder = DirectoryConstants.defaultTempDirectory + "\\" + GUID; Directory.CreateDirectory(guidFolder); int chunkLength = jobParams.ChunkDuration; // sec int outputFPS = jobParams.FrameRate; double chunkOverlap = jobParams.ChunkOverlap; // sec var client = new WebClient(); if (jobParams.DataSrcFormat == DataFormat.Video) { // sample to frames int noFramePerChunk = (int)(chunkLength * outputFPS); int noFrameOverlap = (int)(chunkOverlap * outputFPS); List <string> videoUrls = bcm.getURLList(job.azureInformation.AzureBlobStorageContainerName, job.azureInformation.AzureBlobStorageContainerDirectoryName); foreach (string video in videoUrls) { string videoName = URIUtilities.filenameFromURINoExtension(video); string videonameExtension = URIUtilities.filenameFromURI(video); string outputDirectory = guidFolder + "\\" + videoName; Directory.CreateDirectory(outputDirectory); client.DownloadFile(video, outputDirectory + "\\" + videonameExtension); FFMpegWrappers.ExtractFrames(DirectoryConstants.ffmpeg, outputDirectory + "\\" + videonameExtension, outputDirectory, videoName, DateTime.Now, outputFPS); Console.WriteLine("deleting downloaded file..."); File.Delete(outputDirectory + "\\" + videonameExtension); GroupFramesIntoChunksAndUploadChunks(videoName, outputDirectory, noFramePerChunk, noFrameOverlap, satyamContainerName, satyamDirectoryName); Directory.Delete(outputDirectory, true); } } if (jobParams.DataSrcFormat == DataFormat.VideoFrame) { int noFramePerChunk = (int)(chunkLength * outputFPS);//just use one fps for now, assume input should've already downsampled int noFrameOverlap = (int)(chunkOverlap * outputFPS); // chunk according to parameters List <string> frameUrls = bcm.getURLList(job.azureInformation.AzureBlobStorageContainerName, job.azureInformation.AzureBlobStorageContainerDirectoryName); Dictionary <string, List <string> > framesPerVideo = new Dictionary <string, List <string> >(); foreach (string url in frameUrls) { // assumed hierarchy: blob/directory.../videoname/frameid.jpg //string frameName = URIUtilities.filenameFromURINoExtension(url); string[] urlparts = url.Split('/'); string videoName = urlparts[urlparts.Length - 2]; if (!framesPerVideo.ContainsKey(videoName)) { framesPerVideo.Add(videoName, new List <string>()); } framesPerVideo[videoName].Add(url); } foreach (string video in framesPerVideo.Keys) { string outputDirectory = guidFolder + "\\" + video; Directory.CreateDirectory(outputDirectory); foreach (string frameURL in framesPerVideo[video]) { string frameName = URIUtilities.filenameFromURI(frameURL); client.DownloadFile(frameURL, outputDirectory + "\\" + frameName); } GroupFramesIntoChunksAndUploadChunks(video, outputDirectory, noFramePerChunk, noFrameOverlap, satyamContainerName, satyamDirectoryName); Directory.Delete(outputDirectory, true); } } return(true); }
public static ImageSegmentationAggregatedResult getAggregatedResult(List <ImageSegmentationResult> originalResults, string SatyamURL, string guid, int MinResults = TaskConstants.IMAGE_SEGMENTATION_MTURK_MIN_RESULTS_TO_AGGREGATE, int MaxResults = TaskConstants.IMAGE_SEGMENTATION_MTURK_MAX_RESULTS_TO_AGGREGATE, double CategoryMajorityThreshold = TaskConstants.IMAGE_SEGMENTATION_MTURK_MAJORITY_CATEGORY_THRESHOLD, double PolygonBoundaryMajorityThreshold = TaskConstants.IMAGE_SEGMENTATION_MTURK_MAJORITY_POLYGON_BOUNDARY_THRESHOLD, double ObjectsCoverageThreshold = TaskConstants.IMAGE_SEGMENTATION_MTURK_OBJECT_COVERAGE_THRESHOLD_FOR_AGGREGATION_TERMINATION, double minSimilarityThreshold = TaskConstants.IMAGE_SEGMENTATION_MTURK_POLYGON_IOU_THRESHOLD, int minResultsForConsensus = TaskConstants.IMAGE_SEGMENTATION_MTURK_MIN_RESULTS_FOR_CONSENSUS ) { List <ImageSegmentationResult> results = new List <ImageSegmentationResult>(); // Warning: filter empty results: strong assumption that there has to be something for now!!! for (int i = 0; i < originalResults.Count; i++) { if (originalResults[i] != null && originalResults[i].objects.Count != 0) { results.Add(originalResults[i]); } } Console.WriteLine("Filetered Results: {0}", results.Count); if (results.Count < MinResults) //need at least three results! { return(null); } int ImageWidth = results[0].imageWidth; int ImageHeight = results[0].imageHeight; //auto padding data to make the stride a multiple of 4. required by bmpdata for output int paddedWidth = ImageWidth; if (paddedWidth % 4 != 0) { paddedWidth = (paddedWidth / 4 + 1) * 4; } byte[] PNG = new byte[ImageHeight * paddedWidth]; ImageSegmentationAggregatedResult aggResult = new ImageSegmentationAggregatedResult(); aggResult.metaData = new ImageSegmentationAggregatedResultMetaData(); aggResult.metaData.TotalCount = results.Count; for (int i = 0; i < PNG.Length; i++) { PNG[i] = 0; } aggResult.boxesAndCategories = new ImageSegmentationResult(); aggResult.boxesAndCategories.objects = new List <ImageSegmentationResultSingleEntry>(); aggResult.boxesAndCategories.displayScaleReductionX = results[0].displayScaleReductionX; aggResult.boxesAndCategories.displayScaleReductionY = results[0].displayScaleReductionY; aggResult.boxesAndCategories.imageHeight = ImageHeight; aggResult.boxesAndCategories.imageWidth = ImageWidth; //first use multipartitie wieghted matching to associated the boxes disregarding the labels since //people might make mistake with lables but boxes are usually right List <List <Segment> > AllPolygons = new List <List <Segment> >(); List <int> noPolygonsPerResult = new List <int>(); foreach (ImageSegmentationResult res in results) { AllPolygons.Add(new List <Segment>()); if (res == null) { noPolygonsPerResult.Add(0); continue; } List <Segment> polygonList = AllPolygons[AllPolygons.Count - 1]; foreach (ImageSegmentationResultSingleEntry entry in res.objects) { polygonList.Add(entry.segment); } noPolygonsPerResult.Add(polygonList.Count); } //now associate boxes across the various results //List<MultipartiteWeightedMatch> polyAssociation = PolygonAssociation.computeGenericPolygonAssociations(AllPolygons); List <MultipartiteWeightedMatch> polyAssociation = GenericObjectAssociation.computeAssociations <Segment>(AllPolygons, Segment.computeIoU_PixelSweep); int noObjects = polyAssociation.Count; int noAssociatedPolygons = 0; //how many of the drawn boxes for each result were actually associated by two or more people for each user? SortedDictionary <int, int> noMultipleAssociatedPolygonsPerResult = new SortedDictionary <int, int>(); for (int i = 0; i < results.Count; i++) { noMultipleAssociatedPolygonsPerResult.Add(i, 0); } foreach (MultipartiteWeightedMatch match in polyAssociation) { if (match.elementList.Count > 1) //this has been corroborated by two people { noAssociatedPolygons++; foreach (KeyValuePair <int, int> entry in match.elementList) { noMultipleAssociatedPolygonsPerResult[entry.Key]++; } } } //count how many people have a high association ratio int noHighAssociationRatio = 0; for (int i = 0; i < results.Count; i++) { if (noPolygonsPerResult[i] == 0) { continue; } double ratio = (double)noMultipleAssociatedPolygonsPerResult[i] / (double)noPolygonsPerResult[i]; if (ratio > ObjectsCoverageThreshold) { noHighAssociationRatio++; } } if (noHighAssociationRatio < MinResults && results.Count < MaxResults) //at least three people should have all their boxes highly corroborated by one other person { return(null); } //int noAcceptedPolygons = 0; SortedDictionary <int, List <int> > noHighQualityAssociation = new SortedDictionary <int, List <int> >(); for (int idx = 0; idx < polyAssociation.Count; idx++) { MultipartiteWeightedMatch match = polyAssociation[idx]; List <Segment> polyList = new List <Segment>(); List <string> identifiers = new List <string>(); foreach (KeyValuePair <int, int> entry in match.elementList) { polyList.Add(AllPolygons[entry.Key][entry.Value]); identifiers.Add(entry.Key + "_" + entry.Value); } SegmentGroup majorityGroup = getMajorityGroupPolygons(identifiers, polyList, minSimilarityThreshold, match.weightMatrix); if (majorityGroup == null) { continue; } if (majorityGroup.segments.Count < minResultsForConsensus) { continue; } Segment aggregatedPolygon = new Segment();// dummy polygon byte[] png = GetAggregatedGenericPolygon_PixelSweep(majorityGroup.segments, ImageWidth, ImageHeight, PolygonBoundaryMajorityThreshold); // log where the results come from foreach (string id in majorityGroup.identifiers) { string[] fields = id.Split('_'); int k = Convert.ToInt32(fields[0]); int v = Convert.ToInt32(fields[1]); if (!noHighQualityAssociation.ContainsKey(k)) { noHighQualityAssociation.Add(k, new List <int>()); } noHighQualityAssociation[k].Add(v); } // category aggregation Dictionary <string, int> categoryNames = new Dictionary <string, int>(); int totalCount = match.elementList.Count; int maxCount = 0; string maxCategory = ""; foreach (KeyValuePair <int, int> entry in match.elementList) { string category = results[entry.Key].objects[entry.Value].Category; if (!categoryNames.ContainsKey(category)) { categoryNames.Add(category, 0); } categoryNames[category]++; if (maxCount < categoryNames[category]) { maxCount = categoryNames[category]; maxCategory = category; } } double probability = ((double)maxCount + 1) / ((double)totalCount + 2); if (probability < CategoryMajorityThreshold && results.Count < MaxResults) //this is not a valid category need more work { return(null); } // now we have one segment ready ImageSegmentationResultSingleEntry aggregated = new ImageSegmentationResultSingleEntry(); aggregated.segment = aggregatedPolygon; aggregated.Category = maxCategory; aggResult.boxesAndCategories.objects.Add(aggregated); for (int i = 0; i < ImageWidth; i++) { for (int j = 0; j < ImageHeight; j++) { int pospng = j * ImageWidth + i; int pos = j * paddedWidth + i; if (PNG[pos] == 0 && png[pospng] != 0) { PNG[pos] = (byte)(idx + 1); } } } } // check no. of high association results int noResultsWithHighQualityObjectCoverage = 0; for (int i = 0; i < results.Count; i++) { if (noPolygonsPerResult[i] == 0) { continue; } if (!noHighQualityAssociation.ContainsKey(i)) { continue; } double ratio = ((double)noHighQualityAssociation[i].Count) / (double)noPolygonsPerResult[i]; if (ratio > ObjectsCoverageThreshold) { noResultsWithHighQualityObjectCoverage++; } } if (noResultsWithHighQualityObjectCoverage < MinResults && results.Count < MaxResults) //at least three people should have most of their boxes highly corroborated by one other person { return(null); } // save and upload to azure string filename = URIUtilities.filenameFromURINoExtension(SatyamURL); //string filepath = DirectoryConstants.defaultTempDirectory + filename + "_aggregated.PNG"; string filepath = DirectoryConstants.defaultAzureTempDirectory + filename + "_aggregated.PNG"; ImageUtilities.savePNGRawData(filepath, ImageWidth, ImageHeight, PNG); SatyamJobStorageAccountAccess blob = new SatyamJobStorageAccountAccess(); string container = SatyamTaskGenerator.JobTemplateToSatyamContainerNameMap[TaskConstants.Segmentation_Image_MTurk]; string directoryPath = guid + "_aggregated"; blob.UploadALocalFile(filepath, container, directoryPath); aggResult.metaData.PNG_URL = TaskConstants.AzureBlobURL + container + "/" + directoryPath + "/" + filename + "_aggregated.PNG"; //clean up File.Delete(filepath); return(aggResult); }