樂法內參導讀:近日,上海知識產權法院(以下簡稱上海知產法院)審結了圍繞兩款動作卡牌手游——《拳皇98終極之戰OL》(以下簡稱《拳皇》)與《數碼大冒險》產生的著作權侵權與不正當競爭糾紛上訴案。該案的爭議焦點之一是有關游戲規則性質的認定。內參叔將以本案為起點,引入網絡游戲的規則引發的糾紛問題。
《拳皇》是由日本SNK官方正版授權,國內游戲公司聯合開發的一款以拳皇為題材的手游;《數碼大冒險》是由上海羽盟網絡科技有限公司(以下簡稱羽盟公司)開發的一款手游,以幻想的數碼世界為背景展開游戲情節。上海知產法院維持一審判決,判令羽盟公司立即停止對《拳皇》游戲的侵權和不正當競爭的行為,并賠償《拳皇》游戲軟件的著作權人――天津益趣科技有限公司(以下簡稱益趣公司)160萬元。
益趣公司參照現行《中華人民共和國著作權法(2010修正)》第3條中關于作品類型的規定,主張《拳皇》屬于類電影作品,應當受到《著作權法》的保護。但是,一審和終審法院均未認同這一主張。法院認為《拳皇》游戲整體不能構成連續畫面,缺乏電影情節的表達方式,因此不構成類電作品。而對于游戲規則設計、規則界面結構設計、人物屬性技能設置等游戲玩法的性質,法院也未認定其受著作權法保護。其中,一審法院認為,《拳皇》游戲的界面、規則說明等內容不構成獨創性表達;二審法院進一步說明,益趣公司主張的游戲玩法是基礎規則,屬于思想范疇,而構成作品的游戲設計應當為具體規則且構成獨創性表達。最終,兩審法院均認定羽盟公司在游戲規則設計上存在明顯抄襲行為,有損益趣公司的智力勞動成果,違背了商業道德和誠實信用原則,構成不正當競爭。
在網絡游戲侵權案例中,最為普遍的便是上文所述案例中蘊含的爭議焦點——對游戲規則玩法的抄襲。由于此類侵權行為較為隱蔽,業界俗稱為“換皮”抄襲,且證明玩法規則的獨創性具有一定難度,導致在實際案例中主張著作權侵權的訴訟請求很難得到法院支持。在此情形下,一部分案例通過反不正當競爭的訴求獲得了法院的支持。在本文中,內參叔將梳理有關游戲玩法規則的侵權類型和法院認定,并總結目前此類維權面臨的困難。
與前文《拳皇》訴《數碼大冒險》游戲侵權一案(下文簡稱《拳皇》案)僅判定不正當競爭的判決不同的是,在《太極熊貓》訴《花千骨》游戲案(下文簡稱《花千骨》案)中,法院認定《太極熊貓》游戲整體畫面中游戲玩法規則的特定呈現方式構成了著作權法保護的客體。
太極熊貓是一款大型角色扮演類手機游戲(下文簡稱RPG)。游戲設定在虛構的伊瓦蘭斯大陸上,由于大陸遭到黑暗的侵襲,玩家需要同游戲內置的NPC主人公一同維護和平。玩家可通過收集裝備套裝、符文合成、煉星等系統來提升角色實力,還可參加實時戰場和多人組隊副本等日常活動。在玩法本身富有劇情的設定下,游戲玩家可獲得沉浸式的視聽體驗,這與觀看電影等視聽作品的欣賞體驗類似。事實上,在2020年最新修正的《著作權法》中,已用“視聽作品”替代了原第3條第6項的“電影作品和以類似攝制電影的方法創作的作品”。這一改動符合當下視聽藝術發展多元化的趨勢。盡管游戲整體被認定為受著作權法保護的作品,但關于游戲規則是否作為具有獨創性的表達而屬于著作權法的保護范疇,還需具體分析規則的內容。對此,該案判決提供了詳細的判定思路。
首先,判定游戲規則屬于思想還是表達的關鍵是看其對規則的描述是否足夠具體。若僅是一般性的、概括性的描述,則此種游戲規則屬于著作權法保護范圍之外的思想領域。在《拳皇》案中,《拳皇》游戲的著作權人益趣公司提供的證據顯示,被訴侵權游戲在游戲規則的文字說明部分和游戲規則的界面部分均與《拳皇》存在多處實質性相似。比如,“拳皇爭霸”對應“王者之戰”、“終極試煉”對應“數碼試煉”;此外,兩游戲的“公會”“競技場”“挑戰系統”等界面包括的細節設計也十分相似。對此,二審法院認定,涉案游戲的規則屬于同類格斗類游戲通用的基礎規則。至于上訴人主張其游戲中的20個系統設計體現了人物形象、性格、技能等具體的表達,法院則認為具體設計的獨創性不能代表整個游戲設計具有獨創性,建議上訴人根據具體設計的性質,將其納入相應的作品類型提出訴訟請求。
那么什么樣的規則屬于具體規則?在《拳皇》案,二審法院給出的定義為:具體規則系在基礎規則的基礎上指引玩家行為的一系列機制及機制的組合,使得整個游戲的玩法與其他游戲相比具有個性或特質。《太極熊貓》案中法院則對具體游戲規則給出了更為直觀的描述,即游戲規則具體到了一定程度足以使玩家產生感知特定作品來源的特有玩賞體驗。此時,游戲規則越過思想與表達的臨界點,構成表達。由于《太極熊貓》游戲的設計師通過游戲連續動態圖像中的游戲界面,將單個游戲系統的具體玩法規則或通過界面內直白的文字形式或通過連續游戲操作界面對外敘述表達,使玩家在操作游戲過程中清晰感知并據此開展交互操作,因而這樣的游戲規則具有表達性。法院還進一步解釋,此類敘事性的游戲規則類似于詳細的電影劇情,具有傳達劇情的效果。
其次,在確認游戲規則屬于表達的范圍內后,下一步需認定其是否具有獨創性。由于無論是網游還是手游,經過多年的發展后逐漸呈現類型化趨勢,即一款已有類型游戲的整體玩法系統不大可能從零開始,而是在已有各類游戲玩法系統的基礎上,進行模塊的選擇、組合、以及部分創新。所以游戲中一些部分即使相同,也并不構成侵權,例如公共部分、功能性部分和有限表達部分。這些已經固定類型的玩法規定不能被任何游戲公司壟斷,但可以對此類規則的特定呈現方式進行獨創性認定,確認其是否產生著作權。
結合其他游戲內容侵權案件,內參叔將在本部分探討游戲規則侵權糾紛中權利人方可能面臨的幾點困難和解決途徑。
首先,根據上一部分的分析可知,和美術作品、故事情節抄襲相比,對挪用游戲規則的抄襲認定不那么容易,因為大多數游戲規則為同類游戲的通用玩法,不能由一家游戲開發公司獨占壟斷。此時,法院會依據《反不正當競爭法》支持涉案游戲方提出的不正當競爭的訴訟請求。正如在《拳皇》案中,在認定涉案游戲規則是格斗類游戲通用的基礎玩法而不構成作品的背景下,法院同時表示,《數碼大冒險》就游戲設計具象化后呈現的圖形、數字、文字、視覺特效等內容的美術設計的全面替換行為,盡管未構成著作權法意義上的實質性相似,但實質保留了《拳皇》但核心游戲規則,在這點上看,羽盟公司存在明顯抄襲行為。二者同為游戲開發公司具有競爭關系,抄襲游戲規則的行為不僅降低了羽盟公司的開發成本,相似的規則還將導致部分《拳皇》玩家流失,導致益趣公司的相關市場受損,屬于“不勞而獲”型的搭便車行為,構成不正當競爭。
其次,被侵權者維權周期長,司法保護具有明顯的滯后性。著作權侵權案件的審判周期普遍在1年以上,這是因為認定侵權行為需對涉案作品進行具體比對,這一環節往往工作量大、細節多。而對于游戲侵權案件,由于涉及軟件設計等更具技術性的知識,在確定涉案作品性質、認定涉案作品與被訴作品是否具有實質性相似時,可能還需咨詢相關產業的從業人員以提供輔助判斷。在大多數手游黃金期只有3個月的背景下,待案件審理完畢,被訴侵權的游戲已完成了利潤的積累,停止侵權行為等判決內容無法對開發者產生明顯的威懾力。
針對上述維權過程中的兩大難處,權利人方可以考慮申請訴前禁令。根據我國《民事訴訟法》第101條的規定,申請保全的利害關系人需滿足3個條件:其一,情況緊急;其二,不及時制止將會使申請人的合法權益受到難以彌補的損害;其三,申請人應當提供擔保。對于本文涉及的情況,可通過《最高人民法院關于審查知識產權糾紛行為保全案件適用法律若干問題的規定》(以下簡稱《規定》)第6條中的兜底條款,即“其他需要立即采取行為保全措施的情況”來保護。而對于“難以彌補的損害”的認定,《規定》第10條列舉了4種情形,其中第2項“被申請人的行為將會導致侵權行為難以控制且顯著增加申請人損害”和第3項“被申請人的侵害行為將會導致申請人的相關市場份額明顯減少”可用于游戲規則侵權案例中。
近20年來,網絡游戲逐漸成為主流娛樂方式,為了吸引更多玩家入局,網游開發公司不斷創新、為玩家帶來新穎有趣的游戲,但其中也不乏試圖走捷徑、不勞而獲的商家,絞盡腦汁“借鑒”已經過市場檢驗大獲成功的游戲模式,通過竊取他人的智力成果來獲利。對此,一方面,法律應當提供更為完備的保護,讓投機分子無機可乘。另一方面,游戲開發商也應當意識到,擁有自己的智力成果才是提升企業核心競爭力的關鍵,否則,即便短期內收益不菲,也終將受到法律的制裁,不僅要歸還不法收益,“抄襲者”的名頭也將為業內人員熟知,實在是得不償失。
參考文獻:
[1](2020)滬73民終33號。
[2](2015)蘇中知民初字第00201號案例。
[3]蔡輝:“游戲玩法侵權難界定,四成訴訟流程超一年”,載《南方都市報》,2018年12月20日,轉載于GameRes游資網,https://www.gameres.com/832103.html,最后訪問日期:2021年3月1日。
來源學會官方公眾號:娛樂法內參 yulefaneican 作者:張羽霄
拳皇97OL》是SNK正版IP授權,并擁有《拳皇97》的移動平臺游戲改編權。3月12日,也就是今日上午11點,拳皇97OL已經熱血首測了,成千上萬的玩家都在期待這一佳作,不過結果最終卻是好多玩家并不能即時體驗到這款游戲,現在測試階段游戲需要激活碼才可以進入,具體游戲要怎么獲得激活碼呢?不清楚的玩家,跟小編一起來看看拳皇97OL怎么獲得激活碼?激活碼獲取途徑一覽。
拳皇97激活碼獲得途徑:
1、官網直接領取:
進入官網:http://kof.wanmei.com/main.html,點擊“快速領號”,填寫設備類型和設備系統,最后填寫手機號就有一定的概率獲得激活碼,官方一般都會短信通知;
2、微信領取:
方式一:打開微信--通訊錄--添加朋友--輸入【拳皇97OL】查找官方公眾號--點擊關注【拳皇97OL】官方公眾號,點擊【發號】領取激活碼;
方式二:打開微信--發現--掃一掃--掃描下方【二維碼圖片】--點擊關注【拳皇97OL】官方公眾號,選擇【發號】領取激活碼。
好了,以上就是拳皇97OL怎么獲得激活碼?激活碼獲取途徑一覽的全部內容了,希望對大家能有幫助。
更多關于拳皇97OL的其他最新活動資訊,實用攻略技巧,還請玩家持續關注超好玩拳皇97OL攻略<<<<點擊!
查 編譯整理
量子位 出品 | 公眾號 QbitAI
小時候的你在游戲中搓著手柄,在現實中是否也會模仿這《拳皇》的動作?用身體控制游戲角色的體感游戲很早就已出現,但需要體感手柄(Wii)或體感攝像頭(微軟Kinect)配合。而現在,筆記本就能幫你做到這一切!
最近,有一位名叫Minko Gechev的軟件工程師實現了在筆記本上玩《真人快打》(Mortal Kombat),只需要一顆前置攝像頭即可。
早在5年前,他就曾展示過體感玩格斗游戲的項目成果:
當時實現方案很簡單,也沒有利用時下流行的AI技術。但是這套算法離完美還相去甚遠,因為需要單色畫面背景作為參照,使用條件苛刻。
5年間,無論是網絡瀏覽器的API,還是WebGL都有了長足的發展。于是這名工程師決定用TensorFlow.js來改進他的游戲程序,并在他個人Blog上放出了完整教程。
量子位對文章做了編譯整理,主要內容是訓練模型識別《真人快打》這款游戲主要有拳擊、踢腿兩種動作,并通過模型輸出結果控制游戲人物做出對應動作。
以下就是他Blog的主要內容:
我將分享用TensorFlow.js和MobileNet創建動作分類算法的一些經驗,全文將分為以下幾部分:
簡單討論使用LSTM進行動作分類
我們將開發一種監督深度學習模型,利用筆記本攝像頭獲取的圖像來分辨用戶是在出拳、出腿或者沒有任何動作。最終演示效果如下圖:
理解本文內容需要有基本的軟件工程和JavaScript知識。如果你有一些基本的深度學習知識會很有幫助,但非硬性要求。
深度學習模型的準確性在很大程度上取決于訓練數據的質量。因此,我們首要的目標是建立一個豐富的訓練數據集。
我們的模型需要識別人物的拳擊和踢腿,所以應當從以下三個分類中收集圖像:
為了這個實驗,我找到兩位志愿者幫我收集圖像。我們總共錄制了5段視頻,每段都包含2-4個拳擊動作和2-4個踢腿動作。由于收集到的是視頻文件,我們還需要使用ffmpeg將之轉化為一幀一幀的圖片:
ffmpeg -i video.mov $filename%03d.jpg
最終,在每個目錄下,我們都收集了大約200張圖片,如下:
注:除了拳擊和踢腿外,圖片目錄中最多的是“其他”部分,主要是走動、轉身、開關視頻錄制的一些畫面。如果這部分內容太多,會有風險導致訓練后的模型產生偏見,把應該歸于前兩類的圖片劃分到“其他”中,因此我們減少了這部分圖片的量。
如果只使用這600張相同環境、相同人物的圖片,我們將無法獲得很高的準確度。為了進一步提高識別的準確度,我們將使用數據增強對樣本進行擴充。
數據增強是一種通過已有數據集合成新樣本的技術,可以幫助我們增加數據集的樣本量和多樣性。我們可以將原始圖片處理一下轉變成新圖,但處理過程不能太過激烈,好讓機器能夠對新圖片正確歸類。
常見的處理圖片的方式有旋轉、反轉顏色、模糊等等。網上已有現成軟件,我將使用一款由Python編寫的imgaug的工具(項目地址見附錄),我的數據增強代碼如下:
np.random.seed(44) ia.seed(44) def main(): for i in range(1, 191): draw_single_sequential_images(str(i), "others", "others-aug") for i in range(1, 191): draw_single_sequential_images(str(i), "hits", "hits-aug") for i in range(1, 191): draw_single_sequential_images(str(i), "kicks", "kicks-aug") def draw_single_sequential_images(filename, path, aug_path): image=misc.imresize(ndimage.imread(path + "/" + filename + ".jpg"), (56, 100)) sometimes=lambda aug: iaa.Sometimes(0.5, aug) seq=iaa.Sequential( [ iaa.Fliplr(0.5), # horizontally flip 50% of all images # crop images by -5% to 10% of their height/width sometimes(iaa.CropAndPad( percent=(-0.05, 0.1), pad_mode=ia.ALL, pad_cval=(0, 255) )), sometimes(iaa.Affine( scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}, # scale images to 80-120% of their size, individually per axis translate_percent={"x": (-0.1, 0.1), "y": (-0.1, 0.1)}, # translate by -10 to +10 percent (per axis) rotate=(-5, 5), shear=(-5, 5), # shear by -5 to +5 degrees order=[0, 1], # use nearest neighbour or bilinear interpolation (fast) cval=(0, 255), # if mode is constant, use a cval between 0 and 255 mode=ia.ALL # use any of scikit-image's warping modes (see 2nd image from the top for examples) )), iaa.Grayscale(alpha=(0.0, 1.0)), iaa.Invert(0.05, per_channel=False), # invert color channels # execute 0 to 5 of the following (less important) augmenters per image # don't execute all of them, as that would often be way too strong iaa.SomeOf((0, 5), [ iaa.OneOf([ iaa.GaussianBlur((0, 2.0)), # blur images with a sigma between 0 and 2.0 iaa.AverageBlur(k=(2, 5)), # blur image using local means with kernel sizes between 2 and 5 iaa.MedianBlur(k=(3, 5)), # blur image using local medians with kernel sizes between 3 and 5 ]), iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)), # sharpen images iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0)), # emboss images iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.01*255), per_channel=0.5), # add gaussian noise to images iaa.Add((-10, 10), per_channel=0.5), # change brightness of images (by -10 to 10 of original value) iaa.AddToHueAndSaturation((-20, 20)), # change hue and saturation # either change the brightness of the whole image (sometimes # per channel) or change the brightness of subareas iaa.OneOf([ iaa.Multiply((0.9, 1.1), per_channel=0.5), iaa.FrequencyNoiseAlpha( exponent=(-2, 0), first=iaa.Multiply((0.9, 1.1), per_channel=True), second=iaa.ContrastNormalization((0.9, 1.1)) ) ]), iaa.ContrastNormalization((0.5, 2.0), per_channel=0.5), # improve or worsen the contrast ], random_order=True ) ], random_order=True ) im=np.zeros((16, 56, 100, 3), dtype=np.uint8) for c in range(0, 16): im[c]=image for im in range(len(grid)): misc.imsave(aug_path + "/" + filename + "_" + str(im) + ".jpg", grid[im])
每張圖片最后都被擴展成16張照片,考慮到后面訓練和評估時的運算量,我們減小了圖片體積,每張圖的分辨率都被壓縮成100*56。
現在,我們開始建立圖片分類模型。處理圖片使用的是CNN(卷積神經網絡),CNN適合于圖像識別、物體檢測和分類領域。
遷移學習
遷移學習允許我們使用已被訓練過網絡。我們可以從任何一層獲得輸出,并把它作為新的神經網絡的輸入。這樣,訓練新創建的神經網絡能達到更高的認知水平,并且能將源模型從未見過的圖片進行正確地分類。
我們在文中將使用MobileNet神經網絡(安裝包地址見附錄),它和VGG-16一樣強大,但是體積更小,在瀏覽器中的載入時間更短。
在這一部分,我們將訓練一個二元分類模型。
首先,我們瀏覽器的游戲腳本MK.js中運行訓練過的模型。代碼如下:
const video=document.getElementById('cam'); const Layer='global_average_pooling2d_1'; const mobilenetInfer=m=> (p): tf.Tensor<tf.Rank>=> m.infer(p, Layer); const canvas=document.getElementById('canvas'); const scale=document.getElementById('crop'); const ImageSize={ Width: 100, Height: 56 }; navigator.mediaDevices .getUserMedia({ video: true, audio: false }) .then(stream=> { video.srcObject=stream; });
以上代碼中一些變量和函數的注釋:
第二步,我們從攝像頭獲取視頻流,作為視頻元素的源。對獲得的圖像進行灰階濾波,改變其內容:
const grayscale=(canvas: HTMLCanvasElement)=> { const imageData=canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height); const data=imageData.data; for (let i=0; i < data.length; i +=4) { const avg=(data[i] + data[i + 1] + data[i + 2]) / 3; data[i]=avg; data[i + 1]=avg; data[i + 2]=avg; } canvas.getContext('2d').putImageData(imageData, 0, 0); };
第三步,把訓練過的模型和游戲腳本MK.js連接起來。
let mobilenet: (p: any)=> tf.Tensor<tf.Rank>; tf.loadModel('http://localhost:5000/model.json').then(model=> { mobileNet .load() .then((mn: any)=> mobilenet=mobilenetInfer(mn)) .then(startInterval(mobilenet, model)); });
在以上代碼中,我們將MobileNet的輸出傳遞給mobilenetInfer方法,從而獲得了從網絡的隱藏層中獲得輸出的快捷方式。此外,我還引用了startInterval。
const startInterval=(mobilenet, model)=> ()=> { setInterval(()=> { canvas.getContext('2d').drawImage(video, 0, 0); grayscale(scale .getContext('2d') .drawImage( canvas, 0, 0, canvas.width, canvas.width / (ImageSize.Width / ImageSize.Height), 0, 0, ImageSize.Width, ImageSize.Height )); const [punching]=Array.from(( model.predict(mobilenet(tf.fromPixels(scale))) as tf.Tensor1D) .dataSync() as Float32Array); const detect=(window as any).Detect; if (punching >=0.4) detect && detect.onPunch(); }, 100); };
startInterval正是關鍵所在,它每間隔100ms引用一個匿名函數。在這個匿名函數中,我們把視頻當前幀放入畫布中,然后壓縮成100*56的圖片后,再用于灰階濾波器。
在下一步中,我們把壓縮后的幀傳遞給MobileNet,之后我們將輸出傳遞給訓練過的模型,通過dataSync方法返回一個一維張量punching。
最后,我們通過punching來確定拳擊的概率是否高于0.4,如果是,將調用onPunch方法,現在我們可以控制一種動作了:
在這部分,我們將介紹一個更智能的模型:使用神經網絡分辨三種動作:拳擊、踢腿和站立。
const punches=require('fs') .readdirSync(Punches) .filter(f=> f.endsWith('.jpg')) .map(f=> `${Punches}/${f}`); const kicks=require('fs') .readdirSync(Kicks) .filter(f=> f.endsWith('.jpg')) .map(f=> `${Kicks}/${f}`); const others=require('fs') .readdirSync(Others) .filter(f=> f.endsWith('.jpg')) .map(f=> `${Others}/${f}`); const ys=tf.tensor2d( new Array(punches.length) .fill([1, 0, 0]) .concat(new Array(kicks.length).fill([0, 1, 0])) .concat(new Array(others.length).fill([0, 0, 1])), [punches.length + kicks.length + others.length, 3] ); const xs: tf.Tensor2D=tf.stack( punches .map((path: string)=> mobileNet(readInput(path))) .concat(kicks.map((path: string)=> mobileNet(readInput(path)))) .concat(others.map((path: string)=> mobileNet(readInput(path)))) ) as tf.Tensor2D;
我們對壓縮和灰階化的圖片調用MobileNet,之后將輸出傳遞給訓練過的模型。 該模型返回一維張量,我們用dataSync將其轉換為一個數組。 下一步,通過使用Array.from我們將類型化數組轉換為JavaScript數組,數組中包含我們提取幀中三種姿勢的概率。
如果既不是踢腿也不是拳擊的姿勢的概率高于0.4,我們將返回站立不動。 否則,如果顯示高于0.32的概率拳擊,我們會向MK.js發出拳擊指令。 如果踢腿的概率超過0.32,那么我們發出一個踢腿動作。
以下就是完整的演示效果:
如果我們收集到更大的多樣性數據集,那么我們搭建的模型就能更精確處理每一幀。但這樣就夠了嗎?顯然不是,請看以下兩張圖:
它們都是踢腿動作,但實際上在視頻中有很大的不同,是兩種不同的動作。
為了識別動作,我們還需要使用RNN(循環神經網絡),RNN的優勢在處理時間序列問題,比如
若要識別動作,我們還需要將數幀畫面輸入CNN,再將輸出結果輸入RNN。
在本文中,我們開發了一個圖像分類模型。為此,我們手動提取視頻幀并收集數據集,將它們分成三個不同的類別,然后使用imgaug進行數據增強。
之后,我們通過MobileNet來解釋什么是遷移學習,以及我們如何利用MobileNet。經過訓練,我們的模型達到了90%以上的準確率!
為了在瀏覽器中使用我們開發的模型,我們將它與MobileNet一起加載,并從用戶的相機中每100ms取出一幀,識別用戶的動作,并使用模型的輸出來控制《真人快打3》中的角色。
最后,我們簡單討論了如何通過RNN來進一步改進我們的模型。
我希望你們能夠和我一樣喜歡這個小項目。
原文地址:
https://blog.mgechev.com/2018/10/20/transfer-learning-tensorflow-js-data-augmentation-mobile-net/
原動作識別項目地址:
https://github.com/mgechev/movement.js
JS版《真人快打》項目地址:
https://github.com/mgechev/mk.js
imgaug:
https://github.com/aleju/imgaug
MobileNet神經網絡:
https://www.npmjs.com/package/@tensorflow-models/mobilenet
— 完 —
*請認真填寫需求信息,我們會在24小時內與您取得聯系。