Чтение текстового файла с помощью OpenCV в Python

#python #opencv

#python #opencv

Вопрос:

У меня есть десятки тысяч текстовых файлов для анализа, где каждый текстовый файл представляет моментальный снимок физического состояния системы во времени. Микросостояние каждого «пикселя» представлено числами с плавающей точкой от 0 до 1. Возможно ли, чтобы OpenCV напрямую считывал текстовый файл без предварительного преобразования текстового файла в формат изображения? Я не хочу создавать десятки тысяч файлов изображений каждый раз, когда я выполняю этот анализ.

Контекст / цель: Я анализирую тепловое моделирование наномагнитной системы, и в конечном итоге мне нужно будет использовать OpenCV для вычисления областей контуров кластеров, сформированных выше определенного порогового значения.

Я включил свою попытку кода ниже, используя тестовый текстовый файл. Система представляет собой квадратную систему с длиной стороны 40, и я анализирую столбец из 40 ^ 2 = 1600 точек данных, который я называю mag (для намагничивания, поскольку это из научно-исследовательского проекта). Я умножаю каждый «пиксель» на 255, чтобы имитировать оттенки серого. Как только программа достигает строки cv2.threshold, я получаю сообщение об ошибке:

~/anaconda/conda-bld/work/opencv-2.4.8/modules/imgproc/src/thresh.cpp:783: ошибка: (-210) в пороговом значении функции

я подозреваю, что это связано с тем, что я имитирую оттенки серого вместо чтения реального файла изображения в оттенках серого.

 import numpy as np
import cv2
SideDim = 40

dud, mag = np.loadtxt('Aex_testfile.txt', unpack=True, usecols=(4,5), skiprows=2)

mag = np.reshape(mag, (SideDim,SideDim))

for row in range(SideDim):
    for col in range(SideDim):
        mag[row][col] = round(255 * mag[row][col])
mag = mag.astype(np.int)

ret,thresh = cv2.threshold(mag,0,255,cv2.THRESH_BINARY)
plt.imshow(thresh,'gray')
  

Комментарии:

1. Я не понимаю, зачем вам для этого нужен opencv. Я не знаю opencv, но ваша пороговая подпись не соответствует, Python: cv.Threshold(src, dst, threshold, maxValue, thresholdType) → None найденной в документах . Каким вы хотите, чтобы был массив? 0 для < .5 и 1> = .5? С numpy это просто.

2. На вопросы легче отвечать, если у них есть доступные примеры. mag = np.arange(0, 1, 1./(40*40)).reshape((40,40)) Было бы справедливым представлением ваших данных для тестирования?

3. Взгляните на класс OpenCV FileStorage. Это позволяет загружать Mat в файл и наоборот. Я не уверен, поддерживается ли это в python, но это работает в C

4. @tdelaney, я не рассказал здесь всю историю о том, зачем мне нужен OpenCV, но я должен был упомянуть об этом. В конечном итоге мне нужно будет позже вычислить области контура (cv2.contourrea) для «больших двоичных объектов», превышающих определенный порог, поэтому крайне важно, чтобы эта проблема была совместима с OpenCV. Должен ли я обновить свой вопрос?

5. @tdelaney, предлагаемый вами 2D-массив адекватен для целей этого вопроса, но не будет точным представлением моих данных (я понимаю, потому что я до сих пор не сказал вам, каковы мои цели). Система, которую я анализирую, со временем формирует кластеры («большие двоичные объекты») со значением 1 (или близким к нему) в разных областях матрицы 40×40. По сути, это тепловое моделирование наномагнитной системы. Моя цель — вычислить среднюю площадь кластеров, сформированных выше определенного порога, с течением времени. Надеюсь, это даст вам всю необходимую контекстную информацию!

Ответ №1:

Что касается вопроса в названии вашего поста:

В Python CV2 не преобразует текст в формат изображения. Вместо этого «изображения» — это просто массивы numpy. Тогда вы правильно используете np.loadtxt для импорта данных (хотя я неравнодушен к np.genfromtxt() , поскольку это немного более надежно).

Что касается ошибки, которую вы получаете:

Код ошибки -210 определяется как:

#define CV_StsUnsupportedFormat -210 /* формат / тип данных не поддерживается функцией*/

cv2.threshold() используется 8-разрядное целое число. Вместо приведения mag как np.int , приведите его как np.uint8 . Это должно исправить вашу ошибку

Другие моменты, на которые следует обратить внимание:

С массивами numpy вам не нужно использовать эти уродливые вложенные циклы для умножения каждого значения на 255. Вместо этого просто сделайте mag * 255 .

Вместо умножения на 255 (что не совсем имеет смысл, если вы не уверены, что ваше максимальное значение равно 1 …), вам действительно следует просто нормализовать свой массив. Что-то вроде (mag / mag.amax()) * 255 было бы лучшим решением.

Вам не нужно открывать CV для этой части программы. Вместо этого вы можете просто сделать это в numpy:

 thresh = 255 * (mag > threshval)
  

это приведет к созданию массива (thresh), который имеет любые значения, превышающие значение threshval, установленное равным 255

В общем, я думаю, вам следовало бы изучить numpy, прежде чем переходить к opencv. Я думаю, вы были бы удивлены тем, как много вы можете сделать в numpy.