Python/OpenCV: преобразование изображений, взятых из захвата

Я пытаюсь преобразовать изображения, полученные с захвата (веб-камеры), и обработать их с помощью OpenCV, но у меня возникают трудности.

При попытке преобразовать изображение в оттенки серого программа вылетает. (Python.exe перестал работать)

Вот основной фрагмент моего кода:

newFrameImageGS = cv.CreateImage ((320, 240), cv.IPL_DEPTH_8U, 1)

for i in range(0,5):
    newFrameImage = cv.QueryFrame(ps3eye)
    cv.CvtColor(newFrameImage,newFrameImageGS,cv.CV_BGR2GRAY)
    golfSwing.append(newFrameImageGS)

Когда я пытаюсь использовать cvConvertScale, я получаю ошибку утверждения:

src.size() == dst.size() && src.channels() == dst.channels()

что имеет смысл, но я довольно запутался в том, как преобразовать входные изображения моей веб-камеры в изображения, которые могут использоваться такими функциями, как cvUpdateMotionHistory() и cvCalcOpticalFlowLK()

Любые идеи? Спасибо.

ОБНОВЛЕНИЕ:

Я преобразовал изображение в оттенки серого вручную следующим образом:

for row in range(0,newFrameImage.height):
            for col in range(0,newFrameImage.width):
                newFrameImageGS[row,col] = (newFrameImage8U[row,col][0] * 0.114 + # B
                                            newFrameImage8U[row,col][1] * 0.587 + # G
                                            newFrameImage8U[row,col][2] * 0.299)  # R

Но это занимает довольно много времени... и я до сих пор не могу понять, почему cvCvtColor вызывает сбой программы.


person Dom M.    schedule 27.11.2009    source источник


Ответы (2)


По какой-то причине CvtColor вызывал сбой программы, когда глубина изображения достигала 8 бит. Когда я преобразовал их в 32-битные, программа больше не вылетала, и все, казалось, работало нормально. Я понятия не имею, почему это так, но, по крайней мере, сейчас это работает.

newFrameImage = cv.QueryFrame(ps3eye)

newFrameImage32F = cv.CreateImage((320, 240), cv.IPL_DEPTH_32F, 3)
cv.ConvertScale(newFrameImage,newFrameImage32F)

newFrameImageGS_32F = cv.CreateImage ((320,240), cv.IPL_DEPTH_32F, 1)
cv.CvtColor(newFrameImage32F,newFrameImageGS_32F,cv.CV_RGB2GRAY)

newFrameImageGS = cv.CreateImage ((320,240), cv.IPL_DEPTH_8U, 1)
cv.ConvertScale(newFrameImageGS_32F,newFrameImageGS)
person Dom M.    schedule 27.11.2009
comment
Спасибо, Доменик (смеется, то же имя). Я наткнулся на это после того, как столкнулся с этой ошибкой и потратил часы, пытаясь ее исправить. - person Dominic Bou-Samra; 29.05.2010
comment
был сбой, потому что вы писали матрицу на 4 типа больше (1 float = 4 байта, т.е. 32F = 4 * 8U) - person fabrizioM; 01.04.2011

Здесь есть распространенная ошибка:

Вы создаете одно изображение в переменной newFrameImageGS перед циклом, затем перезаписываете его содержимое в цикле, которое затем добавляется в список. Результат будет не таким, как вы ожидаете. Список будет содержать пять ссылок на один и тот же экземпляр изображения в конце, поскольку к списку добавляется только ссылка на объект, а не копия объекта, сделанная таким образом. Это изображение будет содержать самый последний кадр, поэтому в результате вы получите пять таких кадров, что, я думаю, не то, что вам нужно. Пожалуйста, просмотрите учебник по Python, если он вам непонятен. Вы можете решить эту проблему, переместив первую строку приведенного выше кода в тело цикла for.

Другие возможности, если исправление вышеперечисленного вам не поможет:

Функция CvtColor кажется правильной для преобразования в оттенки серого, поскольку она может преобразовывать в другое количество каналов.

Согласно данному руководству, для функции CvtColor требуется целевое изображение тот же тип данных, что и источник. Пожалуйста, проверьте еще раз, что newFrameImage является изображением IPL_DEPTH_8U.

person fviktor    schedule 27.11.2009
comment
В порядке. Я попытался переместить этот оператор внутрь цикла, но программа все равно падает. Я также проверил глубину newFrameImage, и она равна 8, так что это тоже должно быть правильно. - person Dom M.; 27.11.2009