OpenCV в Python не может сканировать пиксели - PullRequest
1 голос
/ 14 января 2011

Я застрял с проблемой оболочки Python для OpenCv. У меня есть эта функция, которая возвращает 1, если количество черных пикселей больше, чем порог

def checkBlackPixels( img, threshold ):
    width     = img.width
    height    = img.height
    nchannels = img.nChannels
    step      = img.widthStep
    dimtot   = width * height
    data = img.imageData
    black = 0

    for i in range( 0, height ):
        for j in range( 0, width ):
            r = data[i*step + j*nchannels + 0]
            g = data[i*step + j*nchannels + 1]
            b = data[i*step + j*nchannels + 2]

     if r == 0 and g == 0 and b == 0:
         black = black + 1

     if black >= threshold * dimtot:
        return 1
     else:
        return 0  

Цикл (сканирует каждый пиксель данного изображения) работает хорошо, когда входной сигнал является RGB изображение ... но если вход является одноканальным изображением, я получаю эту ошибку:

for j in range( width ):
TypeError: Nested sequences should have 2 or 3 dimensions

Входное одноканальное изображение (в следующем примере называемое «rg») берется из RGB-изображение с именем 'src', обработанное с помощью cvSplit, а затем cvAbsDiff

cvSplit( src, r, g, b, 'NULL' )
rg = cvCreateImage( cvGetSize(src), src.depth, 1 ) # R - G
cvAbsDiff( r, g, rg )

Я также уже заметил, что проблема связана с различием изображения, полученного из cvSplit ...

Кто-нибудь может мне помочь? Спасибо

Ответы [ 2 ]

4 голосов
/ 10 декабря 2011

widthStep и imageData больше не являются действительными атрибутами для объекта IplImage.Таким образом, правильный способ перебрать каждый пиксель и получить его значение цвета будет

for i in range(0, height):
    for j in range(0, width):

        pixel_value = cv.Get2D(img, i, j)
        # Since OpenCV loads color images in BGR, not RGB
        b = pixel_value[0]
        g = pixel_value[1]
        r = pixel_value[2]

        #  cv.Set2D(result, i, j, value)
        #  ^ to store results of per-pixel
        #    operations at (i, j) in 'result' image

Надеюсь, вы найдете это полезным.

2 голосов
/ 15 января 2011

Какую версию OpenCV и какую оболочку Python вы используете?Я рекомендую использовать OpenCV 2.1 или 2.2 с интерфейсом Python, который поставляется с библиотекой.

Я также рекомендую избегать сканирования пикселей вручную и вместо этого использовать функции низкого уровня, предоставляемые OpenCV (см. Операции над массивами часть документации OpenCV).Этот способ будет менее подвержен ошибкам и намного быстрее.

Если вы хотите посчитать количество черных пикселей в одноканальном изображении или в цветном изображении с установленной ИСП (так что цветное изображение эффективно обрабатывается как одноканальное), вы можете использовать функцию CountNonZero :

def countBlackPixels(grayImg):
    (w,h) = cv.GetSize(grayImg)
    size = w * h
    return size - cv.CountNonZero(grayImg)
...