【OpenGL實踐12】關于緩存區Framebuffer的運用

文章目錄

  • 一、說明
  • 二、幀緩沖區
  • 三、創建新的幀緩沖區
  • 四、附屬裝飾
    • 4.1 紋理圖像
    • 4.2 渲染緩沖區對象圖像
  • 五、使用幀緩沖區
    • 5.1 后期處理
    • 5.2 更改代碼
  • 六、后期處理效果
    • 6.1 色彩處理
    • 6.2 模糊
    • 6.3 Sobel算子
  • 七、結論
  • 練習

一、說明

關于FrameBuffer的使用,是OpenGL的高級使用方式,而這種新誕生的功能有些未知的技術需要逐步熟悉,本篇就是針對它的圖像處理功能展開陳述。

二、幀緩沖區

在前面的章節中,我們了解了 OpenGL 提供的不同類型的緩沖區:顏色、深度和模板緩沖區。這些緩沖區像任何其他 OpenGL 對象一樣占用視頻內存,但到目前為止,除了在創建 OpenGL 上下文時指定像素格式之外,我們幾乎無法控制它們。這種緩沖區組合稱為默認幀緩沖區,正如您所見,幀緩沖區是內存中可以渲染的區域。如果您想獲取渲染結果并對其進行一些附加操作(例如許多現代游戲中的后處理),該怎么辦?

在本章中,我們將討論幀緩沖區對象,這是創建額外的幀緩沖區以進行渲染的一種方法。幀緩沖區的偉大之處在于它們允許您將場景直接渲染到紋理,然后可以在其他渲染操作中使用該紋理。在討論了幀緩沖區對象的工作原理之后,我將向您展示如何使用它們對上一章的場景進行后處理。

三、創建新的幀緩沖區

您需要的第一件事是一個幀緩沖區對象來管理新的幀緩沖區。

GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);

此時您還不能使用此幀緩沖區,因為它還不完整。在以下情況下,幀緩沖區通常是完整的:

至少已附加一個緩沖區(例如顏色、深度、模板)
必須至少有一種顏色附件(OpenGL 4.1 及更早版本)
所有附件均已完成(例如,紋理附件需要保留內存)
所有附件必須具有相同數量的多重樣本
您可以隨時通過調用glCheckFramebufferStatus并檢查它是否返回來檢查幀緩沖區是否完整GL_FRAMEBUFFER_COMPLETE。其他返回值請參閱參考資料。您不必執行此檢查,但驗證通常是一件好事,就像檢查著色器是否成功編譯一樣。

現在,讓我們綁定幀緩沖區來使用它。

glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

第一個參數指定幀緩沖區應附加到的目標。OpenGL 在這里區分了GL_DRAW_FRAMEBUFFER和GL_READ_FRAMEBUFFER。綁定到 read 的幀緩沖區用于 的調用glReadPixels,但由于這種區別在普通應用程序中相當罕見,因此您可以使用 將您的操作應用于兩者GL_FRAMEBUFFER。

glDeleteFramebuffers(1, &frameBuffer);

完成后別忘了清理。

四、附屬裝飾

僅當已分配內存來存儲結果時,您的幀緩沖區才能用作渲染目標。這是通過為每個緩沖區附加圖像(顏色、深度、模板或深度和模板的組合)來完成的。有兩種對象可以用作圖像:紋理對象和渲染緩沖區對象。前者的優點是它們可以直接在著色器中使用,如前面的章節所示,但根據您的實現,渲染緩沖區對象可能會作為渲染目標進行更優化。

4.1 紋理圖像

我們希望能夠渲染一個場景,然后在另一個渲染操作中使用顏色緩沖區中的結果,因此紋理在這種情況下是理想的選擇。創建紋理作為新幀緩沖區顏色緩沖區的圖像與創建任何紋理一樣簡單。

GLuint texColorBuffer;
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL
);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

該紋理與您之前見過的紋理之間的區別在于NULLdata 參數的值。這是有道理的,因為這次將通過渲染操作動態創建數據。由于這是顏色緩沖區的圖像,因此format和internalformat參數受到更多限制。該format參數通常僅限于 或GL_RGB以及GL_RGBA顏色internalformat格式。

我在這里選擇了默認的 RGB 內部格式,但您可以嘗試更奇特的格式,例如GL_RGB10如果您想要 10 位顏色精度。我的應用程序的分辨率為 800 x 600 像素,因此我使這個新的顏色緩沖區與該分辨率相匹配。分辨率不必與默認幀緩沖區相匹配,但glViewport如果您決定改變,請不要忘記調用。

剩下的一件事是將圖像附加到幀緩沖區。

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0 );

第二個參數意味著您可以有多個顏色附件。片段著色器可以通過使用我們之前使用的函數將out變量鏈接到附件來向其中任何一個輸出不同的數據。glBindFragDataLocation我們現在將堅持使用一種輸出。最后一個參數指定圖像應附加到的 mipmap 級別。 Mipmapping 沒有任何用處,因為在使用顏色緩沖區圖像進行后期處理時,它將以其原始大小進行渲染。

4.2 渲染緩沖區對象圖像

由于我們使用深度和模板緩沖區來渲染可愛的旋轉立方體,因此我們也必須創建它們。 OpenGL 允許您將它們組合成一張圖像,因此我們必須再創建一張圖像才能使用幀緩沖區。盡管我們可以通過創建另一個紋理來做到這一點,但將這些緩沖區存儲在渲染緩沖區對象中會更有效,因為我們只對讀取著色器中的顏色緩沖區感興趣。

GLuint rboDepthStencil;
glGenRenderbuffers(1, &rboDepthStencil);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);

創建渲染緩沖區對象與創建紋理非常相似,不同之處在于該對象被設計用作圖像而不是像紋理那樣的通用數據緩沖區。我在這里選擇了GL_DEPTH24_STENCIL8內部格式,它適合分別保存 24 位和 8 位精度的深度緩沖區和模板緩沖區。

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboDepthStencil  );

連接起來也很容易。您可以稍后通過調用刪除該對象,就像刪除任何其他對象一樣glDeleteRenderbuffers。

五、使用幀緩沖區

選擇幀緩沖區作為渲染目標非常容易,實際上只需一次調用即可完成。

glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
在此調用之后,所有渲染操作都將其結果存儲在新創建的幀緩沖區的附件中。要切換回屏幕上可見的默認幀緩沖區,只需傳遞0.

glBindFramebuffer(GL_FRAMEBUFFER, 0);
請注意,雖然只有默認的幀緩沖區在屏幕上可見,但您可以讀取當前與調用綁定的任何幀緩沖區,glReadPixels只要它不僅綁定到GL_DRAW_FRAMEBUFFER.

5.1 后期處理

在當今的游戲中,后處理效果似乎幾乎與屏幕上渲染的實際場景一樣重要,并且實際上可以使用不同的技術來實現一些令人驚嘆的結果。實時圖形中的后處理效果通常在片段著色器中實現,并將渲染的場景作為紋理形式的輸入。幀緩沖區對象允許我們使用紋理來包含顏色緩沖區,因此我們可以使用它們為后處理效果準備輸入。

要使用著色器為先前渲染到紋理的場景創建后處理效果,通常將其渲染為屏幕填充的 2D 矩形。這樣,應用了效果的原始場景就會以其原始大小填充屏幕,就好像它首先被渲染到默認幀緩沖區一樣。

當然,您可以利用幀緩沖區發揮創意,通過從不同角度多次渲染場景并將其顯示在監視器或最終圖像中的其他對象上,使用它們在游戲世界中執行從門戶到攝像機的任何操作。這些用途更加具體,因此我將它們作為練習留給您。

5.2 更改代碼

不幸的是,在這里逐步介紹對代碼的更改有點困難,特別是如果您偏離了此處的示例代碼。現在您已經了解了幀緩沖區是如何創建和綁定的,并且只要小心一點,您應該能夠做到這一點。讓我們全局地完成這里的步驟。

首先嘗試創建幀緩沖區并檢查它是否完整。嘗試將其綁定為渲染目標,您會看到屏幕變黑,因為場景不再渲染到默認幀緩沖區。嘗試更改場景的清晰顏色并讀取它以glReadPixels檢查場景是否正確渲染到新的幀緩沖區。
接下來,嘗試創建一個新的著色器程序、頂點數組對象和頂點緩沖區對象,以 2D(而不是 3D)渲染事物。切換回默認幀緩沖區非常有用,這樣可以輕松查看結果。您的 2D 著色器不需要變換矩陣。嘗試以這種方式在 3D 旋轉立方體場景前面渲染一個矩形。
最后,嘗試將 3D 場景渲染到您創建的幀緩沖區,并將矩形渲染到默認幀緩沖區。現在嘗試使用矩形中幀緩沖區的紋理來渲染場景。
我選擇僅使用 2 個位置坐標和 2 個紋理坐標進行 2D 渲染。我的 2D 著色器如下所示:

#version 150 core
in vec2 position;
in vec2 texcoord;
out vec2 Texcoord;
void main()
{Texcoord = texcoord;gl_Position = vec4(position, 0.0, 1.0);
}
#version 150 core
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D texFramebuffer;
void main()
{outColor = texture(texFramebuffer, Texcoord);
}

使用此著色器,程序的輸出應該與您了解幀緩沖區之前相同。渲染一幀大致如下所示:

// Bind our framebuffer and draw 3D scene (spinning cube)
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glBindVertexArray(vaoCube);
glEnable(GL_DEPTH_TEST);
glUseProgram(sceneShaderProgram);glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texKitten);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texPuppy);// Draw cube scene here// Bind default framebuffer and draw contents of our framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindVertexArray(vaoQuad);
glDisable(GL_DEPTH_TEST);
glUseProgram(screenShaderProgram);glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);glDrawArrays(GL_TRIANGLES, 0, 6);

3D 和 2D 繪圖操作都有自己的頂點數組(立方體與四邊形)、著色器程序(3D 與 2D 后處理)和紋理。您可以看到,綁定顏色緩沖區紋理與綁定常規紋理一樣簡單。請注意,glBindTexture更改 OpenGL 狀態之類的調用相對昂貴,因此請嘗試將它們保持在最低限度。

我認為,無論我在這里解釋程序的總體結構有多好,你們中的一些人只是喜歡看一些新的示例代碼,也許還可以運行diff它以及上一章中的代碼。

六、后期處理效果

我現在將討論各種有趣的后處理效果、它們的工作原理以及它們的外觀。

6.1 色彩處理

反轉顏色是圖像處理程序中常見的一個選項,但您也可以使用著色器自己完成!

由于顏色值是從0.0到 1.0的浮點值,因此反轉通道就像計算一樣簡單1.0 - channel。如果對每個通道(紅色、綠色、藍色)執行此操作,您將得到反轉的顏色。在片段著色器中,可以這樣完成。

outColor = vec4(1.0, 1.0, 1.0, 1.0) - texture(texFramebuffer, Texcoord);

這也會影響 alpha 通道,但這并不重要,因為 alpha 混合默認情況下是禁用的。

在這里插入圖片描述

通過計算每個通道的平均強度可以簡單地實現顏色灰度化。

outColor = texture(texFramebuffer, Texcoord);
float avg = (outColor.r + outColor.g + outColor.b) / 3.0;
outColor = vec4(avg, avg, avg, 1.0);

這工作得很好,但人類對綠色最敏感,對藍色最不敏感,因此更好的轉換可以使用加權通道。

outColor = texture(texFramebuffer, Texcoord);
float avg = 0.2126 * outColor.r + 0.7152 * outColor.g + 0.0722 * outColor.b;
outColor = vec4(avg, avg, avg, 1.0);

6.2 模糊

有兩種眾所周知的模糊技術:框模糊和高斯模糊。后者會產生更高質量的結果,但前者更容易實現,并且仍然相當接近高斯模糊。

在這里插入圖片描述

模糊是通過對像素周圍的像素進行采樣并計算平均顏色來完成的。

const float blurSizeH = 1.0 / 300.0;
const float blurSizeV = 1.0 / 200.0;
void main()
{vec4 sum = vec4(0.0);for (int x = -4; x <= 4; x++)for (int y = -4; y <= 4; y++)sum += texture(texFramebuffer,vec2(Texcoord.x + x * blurSizeH, Texcoord.y + y * blurSizeV)) / 81.0;outColor = sum;
}

您可以看到總共采集了 81 個樣本。您可以更改 X 軸和 Y 軸上的樣本量來控制模糊量。這些blurSize變量用于確定每個樣本之間的距離。較高的樣本數和較低的樣本距離會產生更好的近似值,但也會迅速降低性能,因此請嘗試找到一個良好的平衡點。

6.3 Sobel算子

Sobel算子常用于邊緣檢測算法中,我們來看看它長什么樣。

片段著色器如下所示:

vec4 top         = texture(texFramebuffer, vec2(Texcoord.x, Texcoord.y + 1.0 / 200.0));
vec4 bottom      = texture(texFramebuffer, vec2(Texcoord.x, Texcoord.y - 1.0 / 200.0));
vec4 left        = texture(texFramebuffer, vec2(Texcoord.x - 1.0 / 300.0, Texcoord.y));
vec4 right       = texture(texFramebuffer, vec2(Texcoord.x + 1.0 / 300.0, Texcoord.y));
vec4 topLeft     = texture(texFramebuffer, vec2(Texcoord.x - 1.0 / 300.0, Texcoord.y + 1.0 / 200.0));
vec4 topRight    = texture(texFramebuffer, vec2(Texcoord.x + 1.0 / 300.0, Texcoord.y + 1.0 / 200.0));
vec4 bottomLeft  = texture(texFramebuffer, vec2(Texcoord.x - 1.0 / 300.0, Texcoord.y - 1.0 / 200.0));
vec4 bottomRight = texture(texFramebuffer, vec2(Texcoord.x + 1.0 / 300.0, Texcoord.y - 1.0 / 200.0));
vec4 sx = -topLeft - 2 * left - bottomLeft + topRight   + 2 * right  + bottomRight;
vec4 sy = -topLeft - 2 * top  - topRight   + bottomLeft + 2 * bottom + bottomRight;
vec4 sobel = sqrt(sx * sx + sy * sy);
outColor = sobel;

就像模糊著色器一樣,以有趣的方式采集并組合一些樣本。您可以在其他地方閱讀有關技術細節的更多信息。

七、結論

著色器的一個很酷的事情是,由于顯卡具有巨大的并行處理能力,您可以實時地按像素操作圖像。毫不奇怪,像 Photoshop 這樣的新版本軟件使用顯卡來加速圖像處理操作!還有許多更復雜的效果,例如 HDR、運動模糊和 SSAO(屏幕空間環境光遮擋),但這些效果比單個著色器涉及的工作量要多一些,因此它們超出了本章的范圍。

練習

嘗試通過添加另一個幀緩沖區來實現兩次通過的高斯模糊效果。 (解決方案)
嘗試在 3D 場景中添加一個面板,從不同角度顯示該場景。 (解決方案)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/19364.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/19364.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/19364.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

橫截面分位數回歸

一、分位數回歸簡介 分位數回歸&#xff08;英語&#xff1a;Quantile regression&#xff09;是回歸分析的方法之一。最早由Roger Koenker和Gilbert Bassett于1978年提出。一般地&#xff0c;傳統的回歸分析研究自變量與因變量的條件期望之間的關系&#xff0c;相應得到的回歸…

AI時代的服裝設計師--AIGC

AI時代的服裝設計師--AIGC AIGCAIGC設計能替代真正的設計師嗎森馬T恤設計AIGC優勢、優化 本文記錄于去年參加的一次森馬T恤設計活動的感受。 AIGC 可以說&#xff0c;近期以來&#xff0c;隨著ChatGPT的不斷發展&#xff0c;從ChatGPT-3到ChatGPT-4的飛速發展&#xff0c;AIGC…

Windows和Linux系統部署Docker(2)

目錄 一、Linux系統部署docker 前置環境&#xff1a; 1.安裝需要的軟件包&#xff0c; yum-util 提供yum-config-manager功能 2.添加阿里云 docker-ce 倉庫 3.安裝docker軟件包 4.啟動 docker并設置開機自啟 5.查看版本&#xff1a; 二、windows系統部署docker 1.查看…

Type ‘null‘ is not assignable to type ‘T‘. - ArkTSCheck

設置泛型將參數配置為 null 時拋出了如下異常: Type null is not assignable to type T. T could be instantiated with an arbitrary type which could be unrelated to null. <ArkTSCheck> 解決辦法 在 null 后面添加 ! 即可,以表示該值不會為 null data: T null! 以…

Qt 基于FFmpeg的視頻轉換器 - 轉GIF動圖

Qt 基于FFmpeg的視頻轉換器 - 轉GIF動圖 引言一、設計思路二、核心源碼三、參考鏈接 引言 gif格式的動圖可以通過連續播放一系列圖像或視頻片段來展示動態效果&#xff0c;使信息更加生動形象&#xff0c;可以很方便的嵌入到網頁或者ppt中。上圖展示了視頻的前幾幀轉為gif動圖的…

隨身WIFI 路由器等嵌入式Linux 編程器固件解包打包

一、固件提取 (1)直接使用CH341A編程器提取全量包,適合于無adb場景 (2)使用adb 、dd工具提取rootfs分區,通常是mtd4,一般我們也只需要修改rootfs 二、firmware 分析 Ubuntu18.04及以上,低版本需解決很多依賴問題 安裝python3和pyhton3-pip 1.下載工具 ?git clo…

基于Paraformer的alpha-token強制對齊

1. 基本原理 CIF 作為Parafoemr的核心模塊&#xff0c;用于預測字數和生成聲學向量&#xff0c;從而實現了單輪非自回歸解碼。其中字數的預測主要通過encoder輸出系數alpha的累計得分&#xff0c;滿足通關閾值β1.0即可產生一個token&#xff0c;其中alpha曲線在一定程度上呈現…

Android12.0 SIM卡語言自適應

文章目錄 需求語言設定Settings中語言切換流程檢測到SIM卡&#xff0c;更新系統語言最終修改 需求 要求系統語言跟隨SIM卡的語言變化。 語言設定 (1)系統預置語言, 即在makefile中指定的語言 (2)重啟, 如果未插卡, 則系統語言為預置的語言 (3)重啟插入SIM卡開機, 會自適應為…

【前端】vue+element項目中select下拉框label想要顯示多個值多個字段

Vue Element項目中select下拉框label想要顯示多個值 <el-selectv-model"form.plantId"collapse-tagsfilterableplaceholder"請選擇品種種類"style"width: 270px;"><el-optionv-for"item in plantIdArray":key"item.id&…

前端首屏加載速度慢問題?怎么解決

前端首屏加載速度慢是用戶體驗中的一個關鍵問題&#xff0c;它直接影響用戶對網站的第一印象以及用戶留存率。首屏加載時間是指從用戶輸入網址到頁面首屏內容完全呈現在用戶面前所需的時間。這個指標對于搜索引擎優化&#xff08;SEO&#xff09;和用戶體驗都至關重要。下面將探…

CSS:浮動

? 文檔流&#xff1a; 由于網頁默認是一個二維平面&#xff0c;當我們在網頁中一行行擺放標簽時&#xff0c;塊標簽會獨占一行&#xff0c;行標簽則只占自身大小&#xff0c;這種情況下要實現網頁布局就很麻煩了&#xff0c;所以我們就需要通過一些方法來改變這種默認的布局方…

centos7離線安裝pthon3.8

centos7離線安裝pthon3.8 因服務器無外網環境&#xff0c;所以事先需要把所有離線的依賴都準備好。 安裝前的準備 先在有外網環境的機器上準備依賴 安裝 centos-release-scl 第三方yum源 yum install centos-release-scl安裝 yum 依賴下載插件 yum install yum-plugin-do…

Javascript 位運算符(,|,^,<<,>>,>>>)

文章目錄 一、什么是位運算&#xff1f;二、如何使用1. 位與&#xff08;AND&#xff09;&#xff1a;&用途&#xff08;1&#xff09;數據清零&#xff08;2&#xff09;判斷奇偶 2. 位或&#xff08;OR&#xff09;&#xff1a;|用途&#xff08;1&#xff09;向下取整 3…

GO語言 gin框架 簡述

原文地址 基本路由 Go語言中文文檔 一、簡介 Gin是一個golang的輕量級web框架&#xff0c;性能不錯&#xff0c;API友好。 Gin支持Restful風格的API&#xff0c;可以直接從URL路徑上接收api參數或者URL參數&#xff0c;也可是使用json或者表單 數據綁定的方式接收參數。 Gin響…

【傳知代碼】BERT論文解讀及情感分類實戰-論文復現

文章目錄 概述原理介紹BERT模型架構任務1 Masked LM&#xff08;MLM&#xff09;任務2 Next Sentence Prediction (NSP)模型輸入下游任務微調GLUE數據集SQuAD v1.1 和 v2.0NER 情感分類實戰IMDB影評情感數據集數據集構建模型構建 核心代碼超參數設置訓練結果注意事項 小結 本文…

AIOps在線評測基準首階段建設完成,面向社區發布真實運維數據!

本文根據必示科技算法研究員、產品總監聶曉輝博士在2024 CCF國際AIOps挑戰賽線下宣講會上的演講整理成文。 2024年1月份OpenAIOps社區成立&#xff0c;隨著越來越多的社區成員加入&#xff0c;各項工作在有條不紊的推進中。在線評測基準系統&#xff08;AIOps Live Benchmark&a…

積鼎CFDPro水文水動力模型,專為中小流域洪水“四預”研發的流體仿真技術

水動力模型與水文模型是水利工程與水文學研究中不可或缺的兩大工具。水動力模型著重于流體運動的動力學機制&#xff0c;通過一系列方程組捕捉水流的時空變化&#xff0c;而概念性水文模型則側重于流域尺度的水文循環過程&#xff0c;利用物理概念與經驗關系進行近似模擬。兩者…

Windows系統部署YOLOv5 v6.1版本的訓練與推理環境保姆級教程

文章目錄 一 概述二 依賴環境(prerequisites)2.1 硬件環境2.2 軟件環境 三 環境安裝3.1 創建并激活虛擬環境3.2 安裝Pytorch與torchvision3.3 校驗Pytorch安裝3.4 下載 YOLOv5 v6.1 源碼3.5 安裝 YOLOv5 依賴3.6 下載預訓練模型3.7 安裝其他依賴3.8 測試環境安裝3.9 測試訓練流…

jupyter notebook更改位置

1.找到jupyer的配置文件 一般在c盤用戶的.jupter文件夾下 2. 用記事本打開這個配置文件&#xff0c;定位到c.NotebookApp.notebook_dir /path_to_your_directory 替換你的位置 3.找到jupyer圖標的位置&#xff0c;打開屬性 添加要存放的位置在目標文件的末尾&#xff0c;重新…

python | spacy,一個神奇的 Python 庫!

本文來源公眾號“python”&#xff0c;僅用于學術分享&#xff0c;侵權刪&#xff0c;干貨滿滿。 原文鏈接&#xff1a;spacy&#xff0c;一個神奇的 Python 庫&#xff01; 大家好&#xff0c;今天為大家分享一個神奇的 Python 庫 - spacy。 Github地址&#xff1a;https:/…