#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.