Вопрос ответил, см. Решение в конце вопроса. Другие комментарии / ответы все еще приветствуются.
Так что у меня возникли проблемы с переносом всех моих элементов в одно хранилище памяти, лучшее, что мне удалось сделать, - это перезаписывать хранилище каждый раз и получать только последние элементы, которые перезаписывают его, чего, к сожалению, недостаточно.
Я в первую очередь программист на Java, поэтому я, вероятно, буду использовать некоторые термины Java вместо эквивалента C и, возможно, упомяну неправильные типы при обращении к объектам C, поэтому я заранее одобряю это (и не понимаю начал по указателям).
В конечном итоге я пытаюсь взять все дефекты выпуклости на изображении и сохранить их в одном непрерывном пространстве, которое я затем передам обратно в Java через JNI. Тип магазина не важен, на данном этапе мне просто нужно, чтобы он работал, и я могу поработать над оптомизацией, если мы добьемся успеха, но я думаю, что стек, очередь, список, вектор или что-то подобное сделает эту работу. В настоящее время я пытаюсь циклически добавлять группы объектов CvSeq в один большой CvSeq, я опубликую свой код и обсудю его после публикации:
CvSeq *allDefects;
allDefects = cvCreateSeq(0, sizeof (CvSeq), sizeof (CvConvexityDefect), mem_storage4);
CvContourScanner scanner3 = cvStartFindContours(img_bin, mem_storage3);
while ((c2 = cvFindNextContour(scanner3)) != NULL) {
if (threshold != 0 && cvContourPerimeter(c2) < threshold) {
cvSubstituteContour(scanner3, NULL);
} else { // otherwise create the hull
CvSeq* c_new;
c_new = cvConvexHull2(c2, mem_storage5, CV_CLOCKWISE, 0);
CvMemStorage* storage;
storage = cvCreateMemStorage(0);
defects = cvConvexityDefects(c2, c_new, storage);
allDefects = defects;
// for (int i = 0; i < defects->total; i++){
// cvSeqPush(allDefects, CV_GET_SEQ_ELEM(CvSeq, defects, i));
// }
}
}
Итак, мы создаем сканер и, в то время как мы можем найти контуры, мы делаем это и проверяем, что он больше заданного порога. Предполагая, что это мы создаем вокруг него корпус, а затем находим дефекты между ним и корпусом. Это означает, что дефектов может содержать несколько объектов, которые я хочу добавить к allDefects каждый раз, когда мы зацикливаемся, но единственный способ добиться этого - сделать allDefects равно дефектов означает, что каждый цикл перезаписывается. Вы можете увидеть немного прокомментированного кода, где я пытаюсь выдвинуть его как стек, но он вылетает с ошибкой:
Утверждение не удалось: sizeof (((дефекты)) -> первый [0]) == sizeof (CvSeqBlock) && ((дефекты)) -> elem_size == sizeof (CvSeq), файл vtoolsModified.cpp, строка 1407
В соответствии с документацией «Процедура cvConvexityDefects () возвращает последовательность структур CvConvexityDefect», так что CvSeq полон CvConvexityDefect (s). Подпись cvConvexityDefects в случае, если это поможет:
CVAPI(CvSeq*) cvConvexityDefects( const CvArr* contour, const CvArr*
convexhull, CvMemStorage* storage CV_DEFAULT(NULL));
Итак, чтобы подвести итог, я хочу найти контур, найти его корпус, найти дефекты между ними, добавить все эти дефекты в один большой магазин , повторять до тех пор, пока не останется никаких контуров, вернуть большой магазин со всеми дефектами в Java. Это жирный шрифт, с которым я ищу помощи.
Кто-нибудь может помочь или указать мне в направлении источника, который может? (Я работаю над этой конкретной проблемой уже около 2 недель, поэтому потратил много ресурсов, и да, я чувствую себя действительно глупо из-за того, что не смог понять, что должно быть простым циклом самостоятельно.)
Спасибо
РЕДАКТИРОВАТЬ - более подробно добавлено в результате комментариев.
РЕДАКТИРОВАТЬ 2 - Ответ на вопрос, результирующий, фиксированный код ниже
Похоже, мое непонимание C было основной проблемой. Я предполагал, что мне нужно использовать CvSeq в месте, где я должен был использовать CvConvexityDefect. Исправленный код выглядит следующим образом:
CvSeq *defects;
CvSeq *allDefects;
allDefects = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvConvexityDefect), mem_storage4);
CvContourScanner scanner3 = cvStartFindContours(img_bin, mem_storage3);
while ((c2 = cvFindNextContour(scanner3)) != NULL) {
if (threshold != 0 && cvContourPerimeter(c2) < threshold) {
cvSubstituteContour(scanner3, NULL);
} else { // otherwise create the hull
CvSeq* c_new;
c_new = cvConvexHull2(c2, mem_storage5, CV_CLOCKWISE, 0);
CvMemStorage* storage;
storage = cvCreateMemStorage(0);
defects = cvConvexityDefects(c2, c_new, storage);
// allDefects = defects;
if (defects->total < 100) {
for (int i = 0; i < defects->total; i++) {
CvConvexityDefect* element = CV_GET_SEQ_ELEM(CvConvexityDefect, defects, i);
if (element != 0){
cvSeqPush(allDefects, element); }
}
}
}
}
Вы можете видеть, что я также проверяю, чтобы убедиться, что возвращено менее 100 дефектов (иногда это миллионы, которые разрушают систему), а также чтобы убедиться, что CV_GET_SEQ_ELEM
не возвращает ноль (я не уверен, если это могу вернуть ноль, но я проверю на всякий случай.