Я пытаюсь найти на большом изображении несколько мелких, используя OpenCV SIFT в VS2017 на C#. Итак, у меня есть отдельные изображения и несколько копий основного, которые хранятся в списке закрытом классом. Теперь, когда я вызываю следующий код, он работает нормально (конечно, это последовательные вызовы):
foreach (var obj in temp)
{
results.Add(
searchEngine.Run(
new AirPhoto(obj.map, path),
new AirPhoto(obj.single, obj.adr)))));
}
Я попытался сделать это быстрее, вызвав все results.Add в многопоточном (многозадачном) режиме:
foreach (var obj in temp)
{
tasks.Add(
Task.Factory.StartNew(() =>
results.Add(
searchEngine.Run(
new AirPhoto(obj.map, path),
new AirPhoto(obj.single, obj.adr)))));
}
Task.WaitAll(tasks.ToArray());
Когда изображений меньше 10 (например, 2-9), все работает хорошо, но когда их 10 или более, получаю «System.Runtime.InteropServices.SEHException» в OpenCvSharp.CPlusPlus.dll. Я решил разделить изображения на несколько групп на 5 и вызывать их по очереди (первые 5 обработались, затем идёт вторая группа и так далее...):
List<Task> tasks = new List<Task>();
int i = 0;
while (i < temp.Count)
{
int size = temp.Count;
tasks.Clear();
List<Temp> temp1 = new List<Temp>();
if ((i + 5) < size && i == 0)
{
temp1 = temp.Take(5).ToList();
}
else if ((i + 5) < size && i != 0)
{
temp1 = temp.Skip(i).Take(5).ToList();
}
else
{
temp1 = temp.Skip(i).ToList();
}
foreach (var obj in temp1)
{
tasks.Add(
Task.Factory.StartNew(() =>
results.Add(
searchEngine.Run(
new AirPhoto(obj.map, path),
new AirPhoto(obj.single, obj.adr)))));
}
Task.WaitAll(tasks.ToArray());
i += 5;
}
Но проблема не решается. Иногда (!!!) первые 5 изображений обрабатываются нормально, а ошибка появляется во второй группе, но в большинстве случаев она отображается почти сразу. Блок кода, который вызывает ошибку (в методе searchEngine.Run()):
public Result Run(AirPhoto mainMap, AirPhoto image)
{
SIFT sift = new SIFT();
BFMatcher matcher = new BFMatcher();
Result res = new Result(mainMap, image);
Mat map = new Mat(res.mainMap.fileName);
Mat singleImage = new Mat(res.singleImage.fileName);
Debug.Write(...);
sift.Run(map, null, out res.mainMap.keypoints, res.mainMap.descriptors);
sift.Run(singleImage, null, out res.singleImage.keypoints, res.singleImage.descriptors); //error there...
res.matches = matcher.Match(res.mainMap.descriptors, res.singleImage.descriptors); // or there
...
return res;
}
Я знаю о существовании async/await, но не придумал, как использовать ихв моем случае.
UPD: это приложение ASP NET MVC 4, но в версии WinForms (щас портирую в веб) все работало нормально. Debug/Release/32/64 - не имеет значения.
UPD2: Ни один из вариантов предложенных @Alias в разных режимах не спас(( Фигня в том, что sift.Run()
, насколько я понял, является обёрткой над кодом чистых плюсов, а их код я открыть не могу - рефлектор шлёт по матери ибо когда эта либа писалась один создатель знает.
StackTrace:
в OpenCvSharp.CPlusPlus.NativeMethods.nonfree_SIFT_run2_OutputArray(IntPtr obj, IntPtr img, IntPtr mask, IntPtr keypoints, IntPtr descriptors, Int32 useProvidedKeypoints)
в OpenCvSharp.CPlusPlus.SIFT.Run(InputArray img, InputArray mask, KeyPoint[]& keypoints, OutputArray descriptors, Boolean useProvidedKeypoints)
в SharedLogic.SearchEngine.Run(AirPhoto mainMap, AirPhoto image) в D:\CVSharp\SharedLogic\SearchEngine.cs:строка 35
А создаёт исключение изначально
TargetSite {Void nonfree_SIFT_run2_OutputArray(IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, Int32)} System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
Вопрос не в том, почему оно бросает исключение, а в том, почему именно на сервере? Может, нужно дать IIS больше ресурсов или потоков? Если это возможно, конечно
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Написал приложение клиент для соц сети на C# и дефендер считает его вирусом что за беспредел? Trojan:Win32/SpriskyW!cl
Пишу пользовательскую функцию для MS SQL Server 2012Внутри использую передачу данных по HTTP и сборку System
Изучаю библиотечный класс ArrayList и не могу понять какую функцию несет переменная private int _version; ? Строка 48:
Этот вопрос является логическим продолжеием этого вопросаЯ попытался реализовать схему, изложенную здесь , но программа не работает