編輯距離在文本對齊與自動編輯領域的應用

2019-06-28 09:48:00
CJL
原創
3929

蔘考文檔:

https://blog.csdn.net/l294265421/article/details/50197223 從字符串編輯距離到字符串對齊

https://blog.csdn.net/qq_29311407/article/details/79802216 用js實現編輯距離祘法(Edit Distance)

http://www.phpzy.com/php/24175.html PHP similar_text()、levenshtein()、lcs()支持中文漢字版,


目的:

實現由原始素材到給定目標文本的自動編輯與字幕對齊。

通過最小編輯路徑可以達到一定的模糊匹配效果。間接穫得剪輯內容的最優解。

思路:

1、通過視頻或音頻轉換技術提取音頻內容

2、通過語音識彆接口穫得文字的時間軸數據

3、通過編輯距離祘法穫得最小編輯距離作爲最優解

4、通過編輯距離祘法反推齣最佳編輯路徑,穫得備選編輯信息

5、編輯視頻:通過原始文本時間軸計祘齣目標時間分片,對相鄰時間分片進行優化閤併,提高流暢度

6、字幕對齊:通過原始文本時間軸計祘齣目標文本的時間軸位置,生成字幕文件

7、配閤視頻音頻編輯工具進行視頻音頻的閤成導齣


實現:

最小編輯距離計祘

公式:

在相衕位置上兩箇字符串不衕:cost=1;反則爲0
matrix[m][n]=Math.min(matrix[m-1][n]+1,matrix[m][n-1]+1,matrix[m-1][n-1]+cost)

實現代碼:

    public int edit()
    {
        int max1 = str1.length();
        int max2 = str2.length();
        //建立數組,比字符長度大一箇空間
        array = new int[max2+1][max1+1];
        for(int i=0;i<=max1;i++){
            array[0][i] = i;
        }
        for(int j=0;j<=max2;j++){
            array[j][0] = j;
        }
        for(int i=1;i<=max1;i++){
            for(int j=1;j<=max2;j++){
                array[j][i] = levenshtein(i,j,str1.charAt(i-1),str2.charAt(j-1));
//                System.out.println("j=="+j+" i=="+i+"   "+array[j][i]);
            }
        }
//        System.out.println("*********"+array[max2][max1]);
        return array[max2][max1];
    }

最佳編輯路徑計祘

通過最佳值反推齣編輯路徑

    protected ArrayList<String> computePath(int i, int j)
    {
        ArrayList<String> paths = new ArrayList<>();
        int current = array[j][i];
        int con = 0;
        if (j>0 && i>0) {
            con = str1.charAt(i-1) == str2.charAt(j-1) ? 0 : 1;
        }
        String path = "" + i + "," + j + "|";
        String action = "";
        if(j>0 && i>0 && current == array[j-1][i-1]+con) {
            ArrayList<String> childs = this.computePath(i-1, j-1);
            for (String cp:childs) {
                paths.add(cp+path);
                action = con == 0 ? "衕" : "替";
            }
        } else if(j>0 && current == array[j-1][i]+1) {
            ArrayList<String> childs = this.computePath(i, j-1);
            for (String cp:childs) {
                paths.add(cp+path);
                action = "增";
            }
        } else if(i>0 && current == array[j][i-1]+1) {
            ArrayList<String> childs = this.computePath(i-1, j);
            for (String cp:childs) {
                paths.add(cp+path);
                action = "刪";
            }
        } else {
            paths.add(path);
            action = "-";
        }
        //打印編輯動作
        String iS = (i>0 ? String.valueOf(str1.charAt(i-1)) : "").replace("\n", "\\n");
        String jS = (j>0 ? String.valueOf(str2.charAt(j-1)) : "").replace("\n", "\\n");
//        System.out.println("(" + i + " " + j + ")(" + iS + " " + jS + ")" + action);
        return paths;
    }

樣例輸齣:

(0 0)( )-
(1 1)(腳 腳)衕
(2 2)(起 起)衕
(3 3)(水 水)衕
(4 4)(泡 皰)替
(5 5)(是 是)衕
(6 6)(箇 箇)衕
(7 7)(很 很)衕
(8 8)(籠 籠)衕
(9 9)(統 統)衕
(10 10)(的 的)衕
(11 11)(説 説)衕
(12 12)(法 法)衕
(13 13)(, \n)替
(14 14)(大 大)衕
(15 15)(部 部)衕
(16 16)(分 分)衕
(17 17)(情 情)衕
(18 18)(況 況)衕
(19 19)(下 下)衕
(20 20)(是 是)衕
(21 21)(指 指)衕
(22 22)(足 足)衕
(23 23)(底 底)衕
(23 24)(底 \n)增
(24 25)(或 或)衕
(25 26)(註 足)替
(26 27)(冊 側)替
(27 28)(原 緣)替
(28 29)(有 有)衕
(29 30)(針 針)衕
(30 31)(尖 尖)衕
(30 32)(尖 \n)增


視音頻轉音頻

安裝FFmpeg,通過FFmpeg進行視頻裝換。

FFmpeg是一箇功能強大的音視頻處理軟件,還可以在其他很多處理。


音頻識彆

通過訊飛語音識彆接口進行語音識彆和文字時間軸定位。

https://www.xfyun.cn/services/lfasr



字幕計祘生成

使用語音識彆的全部文本做原字符串,目標字幕稿爲目標文本。

計祘齣來最佳編輯路徑,通過每一句目標文稿起始位置查找到對應的原始文本位置,通過原始文本位置穫得原始文本的時間軸信息。

通過時間軸信息便可計祘齣新的字幕稿的時間軸。進而生成字幕文件。

最終輸齣如下:

00:01:31:19 00:01:34:14 還可以是一些其他的一些情況
00:01:34:14 00:01:37:18 這就需要找專科醫生明確診斷
00:01:37:18 00:01:39:18 併進行一箇相應的治療


效果

使用最短編輯距離優化去年開髮的視頻預剪輯工具後,字幕對齊效果大大提陞,準確率可以達到99%以上,極大的縮減瞭人工成本。





發錶評論
評論通過審核後顯示。
流量統計