0 ''' Bins1 = Bins[: T] Bins2 = Bins[T:] Prob1 = Bins1.sum() Prob2 = Bins2.sum() Aver1 = sum(Bins1 * Middles[: T])/Prob1 Aver2 = sum(Bins2 * Middles[T: ])/Prob2 return Prob1 * (Aver1 — Aver)**2 \ + Prob2 *(Aver2 — Aver) **2 Bins = np.float_(Bins) NumBins = len(Bins) Middles = np.zeros(NumBins) for I in range(len(Middles)): Middles[I] = Interv[I] + Interv[I+1] Middles *= 0.5 BinsSum = Bins.sum() Bins /= BinsSum # Probabilities Aver = sum(Bins * Middles) Results = np.zeros(NumBins — 1) for I in range(1,NumBins): Results[I -1] = oneStep(I) MxRes = np.amax(Results) Pos = np.where(Results == MxRes) return Middles[Pos[0][0] + 1] Посмотрим на результат обработки того-же файла с помощью алгоритма Отсу Bins,Interv = np.histogram(Std) Level = otsu(Bins,Interv) Result = np.where(Std Мы разбили все интервалы на два класса, и теперь можем раскрасить тот же файл согласно новом разбиению. Полученный график имеет вид схожий с рисунком, полученным на основе kmeans.
Разбиение на слова
Имея классификацию интервалов, можно попытаться выделить отдельные слова в файле. В основе процедуры "разделение" лежит следующая гипотеза. Слова разделяются последовательностью ШИ. Если ШИ оказался внутри слова, то это интервал между слогами. ШИ предшествующие слову и завершающие его включаются в слово. Заменяя каждый интервал нулем и единицей в зависимости от отнесения его к шуму или информации, получим ступенчатую последовательность Step. Разбиение на слова производится на основе этой последовательности.
Первая проблема, которую нужно решить — найти длины интервалов из нулей (или единиц) в этой ступенчатой последовательности. Таким образом вычисляется истинная длина интервала между отдельными информационным отрезками файла. Фактически мы пытаемся выделить границы слова, поэтому ищем интервалы, состоящие из 1. Такие интервалы назовем сегментами. Выделение сегментов из ступенчатой функции осуществляется с помощью функций 𝑠𝑒𝑙𝑒𝑐𝑡𝑆𝑒𝑔𝑚 и 𝑝𝑎𝑖𝑟𝑠11.
Первая функция превращает входную последовательность в строку, а вторая находит все сегменты в этой строке. Функция возвращает множество пар, определяющих начало и конец сегментов. В результате классификации каждый интервал заменяется нулем или единицей. Эту последовательность превращаем в одну строку.
def selectSegm(Step):
Marks2Str = [str(X) for X in Step]
Str = ''.join(Marks2Str)
Segms = pairs11(Str)
return Segms
Теперь в этой строке надо найти начало и конец каждого интервала, состоящего из 1.
def pairs11(A):
Out = []
if A[-1] == '1':
A = A + '0'
if A[0] == '1':
End =A.find('10')
Out.append(((0,End+1)))
Beg = End + 1
else:
Beg = 0
while True:
Beg = A.find('01',Beg)
if Beg == -1:
break
else:
End = Beg+1
End = A.find('10',End)
if End == -1:
break
else:
Out.append([Beg+1,End+1])
Beg = End +1
return Out
Вот пример, поясняющий работу этой функции. Исходная последовательность Step = np.int_([1,0,0,1,1,1,0,1,1]) превращается в строку A=’100111011’, а затем находим границы интервалов из 1.
Pairs = selectSegm(А)
print(Pairs)
[(0, 1), [3, 6], [7, 9]]