Ответ:
проблема с тем, что вы хотите сделать (помимо очевидного, opencv не позволит вам), заключается в том, что радиус не может быть правильно деформирован. AFAIK Координаты xy довольно легко вычислить x '= ((m00x + m01y + m02) / (m20x + m21y + m22)) y' = ((m10x + m11y + m12) / (m20x + m21y_m22)), когда m матрица преобразования. радиус, который вы можете взломать, преобразовав все точки исходного круга, а затем найдите максимальное расстояние между x'y 'и этими точками (по крайней мере, если радиус в искаженном изображении должен охватывать все эти точки)
btw, mIJx = m (i, j) * x (просто чтобы уточнить)
Конечный ответ.
Все, что я пишу, соответствует версии c ++, я никогда не использовал JavaCV, но из того, что я видел, это просто оболочка, которая вызывает нативную библиотеку c ++.
CvSeq - это структура данных sequance, которая ведет себя как связанный список.
Утверждение, что ваше приложение сокрушается в
CV_Assert(seq->total > 0 && CV_ELEM_SIZE(seq->flags) == seq->elem_size);
, что означает, что ваш экземпляр seq пуст (total равно количеству элементов в последовательности) или что-то внутренние флаги seq повреждены.
Я бы порекомендовал вам проверить общего члена вашего CvSeq и вызов cvHoughCircles.
все это происходит до фактической реализации cvWarpPerspective (это первая строка в реализации, которая конвертирует только ваш CvSeq в cv :: Mat) .. так что это не перекос, а то, что вы делали до этого.
в любом случае, чтобы понять, что не так с cvHoughCircles, нам понадобится дополнительная информация о создании newGray и кругов.
вот пример, который я нашел на странице javaCV ( Ссылка )
IplImage gray = cvCreateImage( cvSize( img.width, img.height ), IPL_DEPTH_8U, 1 );
cvCvtColor( img, gray, CV_RGB2GRAY );
// smooth it, otherwise a lot of false circles may be detected
cvSmooth(gray,gray,CV_GAUSSIAN,9,9,2,2);
CvMemStorage circles = CvMemStorage.create();
CvSeq seq = cvHoughCircles(gray, circles.getPointer(), CV_HOUGH_GRADIENT,
2, img.height/4, 100, 100, 0, 0);
for(int i=0; i<seq.total; i++){
float xyr[] = cvGetSeqElem(seq,i).getFloatArray(0, 3);
CvPoint center = new CvPoint(Math.round(xyr[0]), Math.round(xyr[1]));
int radius = Math.round(xyr[2]);
cvCircle(img, center.byValue(), 3, CvScalar.GREEN, -1, 8, 0);
cvCircle(img, center.byValue(), radius, CvScalar.BLUE, 3, 8, 0);
}
из того, что я видел в реализации cvHoughCircles, ответ сохраняется в баффе кругов, и в конце они создают из него CvSeq для возврата, поэтому, если вы неправильно распределили бафф кругов, он не будет работать .
EDIT:
, как вы можете видеть, экземпляр CvSeq в случае возврата из cvHoughCircles представляет собой список значений точек, поэтому, вероятно, утверждение не удалось. Вы не можете конвертировать этот CvSeq в cv :: Mat .. потому что он просто не cv :: Mat. чтобы получить только круги, возвращенные из cvHoughCircles в экземпляре cv :: Mat, вам нужно создать новый экземпляр cv :: Mat и затем нарисовать на нем все круги в CvSeq - как видно из приведенного выше примера.
чем сработает деформация (у вас будет экземпляр cv :: Mat, и именно этого ожидает функция - cv :: Mat как единственный элемент в CvSeq)
END EDIT
здесь - ссылка на C ++ для CvSeq
и если вы хотите возиться с исходным кодом, чем
cvarrToMat находится в matrix.cpp
CV_ELEM_SIZE находится в types_c.h
cvWarpPerspective находится в imgwarp.cpp
cvHoughCircles находится в hough.cpp
Надеюсь, это поможет.
Кстати, ваша следующая ошибка, вероятно, будет:
cv :: warpPerspective в C ++ OpencCv утверждает, что dst.data != src.data
таким образом
cvWarpPerspective(seq, seq, mmat);
не сработает, потому что ваш исходный мат и целевой мат ссылаются на одни и те же данные.
Не все функции в OpenCV (и обработке изображений в целом) работают in-situ (потому что не существует алгоритма in-situ или потому что он медленнее, чем в другой версии, например, транспонирование n * n мата работать на месте, но n * m, где n! = m будет сложнее сделать на месте и может быть медленнее)
Вы не можете предполагать использование матрицы src, поскольку dst будет работать.