国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 後端開發(fā) Python教學 [Python-CV影像分割:Canny邊緣、分水嶺和K-Means方法

[Python-CV影像分割:Canny邊緣、分水嶺和K-Means方法

Dec 11, 2024 am 05:33 AM

分割是影像分析中的基本技術,它允許我們根據(jù)物件、形狀或顏色將影像劃分為有意義的部分。它在物體檢測、電腦視覺甚至藝術圖像處理等應用中發(fā)揮關鍵作用。但如何才能有效實現(xiàn)細分呢?幸運的是,OpenCV (cv2) 提供了幾種用戶友好且強大的分割方法。

在本教學中,我們將探討三種流行的分割技術:

  • Canny 邊緣偵測 – 非常適合勾畫物體輪廓。
  • 分水嶺演算法 – 非常適合分離重疊區(qū)域。
  • K-Means 顏色分割 – 非常適合將影像中的相似顏色進行聚類。

為了使本教程引人入勝且實用,我們將使用來自日本大阪的衛(wèi)星和航空圖像,重點關注古代古墳。您可以從教學的 GitHub 頁面下載這些圖像和相應的範例筆記本。

Canny 邊緣偵測到輪廓分割

Canny 邊緣偵測是一種簡單且強大的方法來辨識影像中的邊緣。它的工作原理是檢測強度快速變化的區(qū)域,這些區(qū)域通常是物體的邊界。該技術透過應用強度閾值來產(chǎn)生“薄邊緣”輪廓。讓我們深入了解它使用 OpenCV 的實作。

範例:偵測衛(wèi)星影像中的邊緣
在這裡,我們使用大阪的衛(wèi)星圖像,特別是古墳,作為測試案例。

import cv2 
import numpy as np
import matplotlib.pyplot as plt
files = sorted(glob("SAT*.png")) #Get png files 
print(len(files))
img=cv2.imread(files[0])
use_image= img[0:600,700:1300]
gray = cv2.cvtColor(use_image, cv2.COLOR_BGR2GRAY)

#Stadard values 
min_val = 100
max_val = 200
# Apply Canny Edge Detection
edges = cv2.Canny(gray, min_val, max_val)
#edges = cv2.Canny(gray, min_val, max_val,apertureSize=5,L2gradient = True )
False
# Show the result
plt.figure(figsize=(15, 5))
plt.subplot(131), plt.imshow(cv2.cvtColor(use_image, cv2.COLOR_BGR2RGB))
plt.title('Original Image'), plt.axis('off')
plt.subplot(132), plt.imshow(gray, cmap='gray')
plt.title('Grayscale Image'), plt.axis('off')
plt.subplot(133), plt.imshow(edges, cmap='gray')
plt.title('Canny Edges'), plt.axis('off')
plt.show()

[Python-CVImage Segmentation : Canny Edges, Watershed, and K-Means Methods

輸出邊緣清晰地勾勒出古墳和其他感興趣區(qū)域的部分輪廓。然而,由於閾值過大,一些區(qū)域被遺漏了。結(jié)果在很大程度上取決於 min_val 和 max_val 的選擇以及影像品質(zhì)。

為了增強邊緣偵測,我們可以對影像進行預處理以分散像素強度並減少雜訊。這可以使用直方圖均衡 (cv2.equalizeHist()) 和高斯模糊 (cv2.GaussianBlur()) 來實現(xiàn)。

use_image= img[0:600,700:1300]
gray = cv2.cvtColor(use_image, cv2.COLOR_BGR2GRAY)
gray_og = gray.copy()
gray = cv2.equalizeHist(gray)
gray = cv2.GaussianBlur(gray, (9, 9),1)

plt.figure(figsize=(15, 5))
plt.subplot(121), plt.imshow(gray, cmap='gray')
plt.title('Grayscale Image')
plt.subplot(122)
_= plt.hist(gray.ravel(), 256, [0,256],label="Equalized") 
_ = plt.hist(gray_og.ravel(), 256, [0,256],label="Original",histtype='step')
plt.legend()
plt.title('Grayscale Histogram')

[Python-CVImage Segmentation : Canny Edges, Watershed, and K-Means Methods

這種預處理可以均勻強度分佈並平滑影像,這有助於 Canny 邊緣偵測演算法捕捉更有意義的邊緣。

邊緣很有用,但它們僅表示邊界。為了分割封閉區(qū)域,我們將邊緣轉(zhuǎn)換為輪廓並視覺化它們。

# Edges to contours 
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Calculate contour areas
areas = [cv2.contourArea(contour) for contour in contours]

# Normalize areas for the colormap
normalized_areas = np.array(areas)
if normalized_areas.max() > 0:
    normalized_areas = normalized_areas / normalized_areas.max()

# Create a colormap
cmap = plt.cm.jet

# Plot the contours with the color map
plt.figure(figsize=(10, 10))
plt.subplot(1,2,1)
plt.imshow(gray, cmap='gray', alpha=0.5)  # Display the grayscale image in the background
mask = np.zeros_like(use_image)
for contour, norm_area in zip(contours, normalized_areas):
    color = cmap(norm_area)  # Map the normalized area to a color
    color = [int(c*255) for c in color[:3]]
    cv2.drawContours(mask, [contour], -1, color,-1 )  # Draw contours on the image

plt.subplot(1,2,2)

[Python-CVImage Segmentation : Canny Edges, Watershed, and K-Means Methods

上述方法以代表其相對區(qū)域的顏色突出顯示檢測到的輪廓。這種視覺化有助於驗證輪廓是否形成封閉體或僅形成線條。然而,在此範例中,許多輪廓仍然是未閉合的多邊形。進一步的預處理或參數(shù)調(diào)整可以解決這些限制。

透過結(jié)合預處理和輪廓分析,Canny 邊緣偵測成為辨識影像中物件邊界的強大工具。然而,當物件定義明確且噪音最小時,它的效果最佳。接下來,我們將探索 K 均值聚類以按顏色分割影像,從而為相同資料提供不同的視角。

K均值聚類

K-Means 聚類是資料科學中一種流行的方法,用於將相似的項目分組為聚類,並且它對於基於顏色相似性的圖像分割特別有效。 OpenCV 的 cv2.kmeans 函數(shù)簡化了此過程,使其可以執(zhí)行物件分割、背景移除或視覺分析等任務。

在本節(jié)中,我們將使用 K 均值聚類將古墳墓影像分割為相似顏色的區(qū)域。

首先,我們對影像的 RGB 值套用 K 均值聚類,將每個像素視為一個資料點。

import cv2 
import numpy as np
import matplotlib.pyplot as plt
files = sorted(glob("SAT*.png")) #Get png files 
print(len(files))
img=cv2.imread(files[0])
use_image= img[0:600,700:1300]
gray = cv2.cvtColor(use_image, cv2.COLOR_BGR2GRAY)

#Stadard values 
min_val = 100
max_val = 200
# Apply Canny Edge Detection
edges = cv2.Canny(gray, min_val, max_val)
#edges = cv2.Canny(gray, min_val, max_val,apertureSize=5,L2gradient = True )
False
# Show the result
plt.figure(figsize=(15, 5))
plt.subplot(131), plt.imshow(cv2.cvtColor(use_image, cv2.COLOR_BGR2RGB))
plt.title('Original Image'), plt.axis('off')
plt.subplot(132), plt.imshow(gray, cmap='gray')
plt.title('Grayscale Image'), plt.axis('off')
plt.subplot(133), plt.imshow(edges, cmap='gray')
plt.title('Canny Edges'), plt.axis('off')
plt.show()

[Python-CVImage Segmentation : Canny Edges, Watershed, and K-Means Methods

在分割影像中,古墳和周圍區(qū)域聚集成不同的顏色。然而,噪音和顏色的微小變化會導致簇分散,這會為解釋帶來挑戰(zhàn)。

為了減少噪音並創(chuàng)建更平滑的聚類,我們可以在運行 K-Means 之前應用中位數(shù)模糊。

use_image= img[0:600,700:1300]
gray = cv2.cvtColor(use_image, cv2.COLOR_BGR2GRAY)
gray_og = gray.copy()
gray = cv2.equalizeHist(gray)
gray = cv2.GaussianBlur(gray, (9, 9),1)

plt.figure(figsize=(15, 5))
plt.subplot(121), plt.imshow(gray, cmap='gray')
plt.title('Grayscale Image')
plt.subplot(122)
_= plt.hist(gray.ravel(), 256, [0,256],label="Equalized") 
_ = plt.hist(gray_og.ravel(), 256, [0,256],label="Original",histtype='step')
plt.legend()
plt.title('Grayscale Histogram')

[Python-CVImage Segmentation : Canny Edges, Watershed, and K-Means Methods

模糊的影像會產(chǎn)生更平滑的簇,減少噪音並使分割區(qū)域在視覺上更具凝聚力。

為了更好地理解分割結(jié)果,我們可以使用 matplotlib plt.fill_ Between;
建立獨特簇顏色的顏色圖

# Edges to contours 
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Calculate contour areas
areas = [cv2.contourArea(contour) for contour in contours]

# Normalize areas for the colormap
normalized_areas = np.array(areas)
if normalized_areas.max() > 0:
    normalized_areas = normalized_areas / normalized_areas.max()

# Create a colormap
cmap = plt.cm.jet

# Plot the contours with the color map
plt.figure(figsize=(10, 10))
plt.subplot(1,2,1)
plt.imshow(gray, cmap='gray', alpha=0.5)  # Display the grayscale image in the background
mask = np.zeros_like(use_image)
for contour, norm_area in zip(contours, normalized_areas):
    color = cmap(norm_area)  # Map the normalized area to a color
    color = [int(c*255) for c in color[:3]]
    cv2.drawContours(mask, [contour], -1, color,-1 )  # Draw contours on the image

plt.subplot(1,2,2)

[Python-CVImage Segmentation : Canny Edges, Watershed, and K-Means Methods

這種視覺化可以深入了解影像中的主色及其對應的 RGB 值,這對於進一步分析非常有用。因為我們現(xiàn)在可以屏蔽並選擇我的顏色代碼區(qū)域。

簇的數(shù)量 (K) 顯著影響結(jié)果。增加 K 會創(chuàng)建更詳細的細分,而較低的值會產(chǎn)生更廣泛的分組。為了進行實驗,我們可以迭代多個 K 值。

import cv2 
import numpy as np
import matplotlib.pyplot as plt
files = sorted(glob("SAT*.png")) #Get png files 
print(len(files))
img=cv2.imread(files[0])
use_image= img[0:600,700:1300]
gray = cv2.cvtColor(use_image, cv2.COLOR_BGR2GRAY)

#Stadard values 
min_val = 100
max_val = 200
# Apply Canny Edge Detection
edges = cv2.Canny(gray, min_val, max_val)
#edges = cv2.Canny(gray, min_val, max_val,apertureSize=5,L2gradient = True )
False
# Show the result
plt.figure(figsize=(15, 5))
plt.subplot(131), plt.imshow(cv2.cvtColor(use_image, cv2.COLOR_BGR2RGB))
plt.title('Original Image'), plt.axis('off')
plt.subplot(132), plt.imshow(gray, cmap='gray')
plt.title('Grayscale Image'), plt.axis('off')
plt.subplot(133), plt.imshow(edges, cmap='gray')
plt.title('Canny Edges'), plt.axis('off')
plt.show()

[Python-CVImage Segmentation : Canny Edges, Watershed, and K-Means Methods

不同 K 值的聚類結(jié)果揭示了細節(jié)和簡單性之間的權衡:

?較低的 K 值(例如 2-3):聚類範圍廣泛,區(qū)分清晰,適合高階分割。
?較高的 K 值(例如 12-15):更詳細的分割,但代價是增加複雜性和潛在的過度分割。

K-Means 聚類是一種基於色彩相似性分割影像的強大技術。透過正確的預處理步驟,它可以產(chǎn)生清晰且有意義的區(qū)域。然而,其性能取決於 K 的選擇、輸入影像的品質(zhì)以及所應用的預處理。接下來,我們將探索分水嶺演算法,該演算法利用地形特徵來實現(xiàn)物件和區(qū)域的精確分割。

分水嶺分割

分水嶺演算法的靈感來自地形圖,其中分水嶺劃分流域。此方法將灰階強度值視為高程,有效地創(chuàng)建“峰”和“谷”。透過識別感興趣區(qū)域,該演算法可以分割具有精確邊界的物件。它對於分離重疊物件特別有用,使其成為細胞分割、物件偵測和區(qū)分密集特徵等複雜場景的絕佳選擇。

第一步是預處理影像以增強特徵,然後應用分水嶺演算法。

use_image= img[0:600,700:1300]
gray = cv2.cvtColor(use_image, cv2.COLOR_BGR2GRAY)
gray_og = gray.copy()
gray = cv2.equalizeHist(gray)
gray = cv2.GaussianBlur(gray, (9, 9),1)

plt.figure(figsize=(15, 5))
plt.subplot(121), plt.imshow(gray, cmap='gray')
plt.title('Grayscale Image')
plt.subplot(122)
_= plt.hist(gray.ravel(), 256, [0,256],label="Equalized") 
_ = plt.hist(gray_og.ravel(), 256, [0,256],label="Original",histtype='step')
plt.legend()
plt.title('Grayscale Histogram')

分段區(qū)域和邊界可以與中間處理步驟一起視覺化。

[Python-CVImage Segmentation : Canny Edges, Watershed, and K-Means Methods

# Edges to contours 
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Calculate contour areas
areas = [cv2.contourArea(contour) for contour in contours]

# Normalize areas for the colormap
normalized_areas = np.array(areas)
if normalized_areas.max() > 0:
    normalized_areas = normalized_areas / normalized_areas.max()

# Create a colormap
cmap = plt.cm.jet

# Plot the contours with the color map
plt.figure(figsize=(10, 10))
plt.subplot(1,2,1)
plt.imshow(gray, cmap='gray', alpha=0.5)  # Display the grayscale image in the background
mask = np.zeros_like(use_image)
for contour, norm_area in zip(contours, normalized_areas):
    color = cmap(norm_area)  # Map the normalized area to a color
    color = [int(c*255) for c in color[:3]]
    cv2.drawContours(mask, [contour], -1, color,-1 )  # Draw contours on the image

plt.subplot(1,2,2)

演算法成功辨識不同的區(qū)域並在物件周圍繪製清晰的邊界。在本例中,古墳被精確分割。然而,此演算法的性能在很大程度上取決於閾值處理、噪音去除和形態(tài)學操作等預處理步驟。

加入進階預處理,例如直方圖均衡或自適應模糊,可以進一步增強結(jié)果。例如:

# Kmean color segmentation
use_image= img[0:600,700:1300]
#use_image = cv2.medianBlur(use_image, 15)


 # Reshape image for k-means
pixel_values = use_image.reshape((-1, 3)) if len(use_image.shape) == 3 else use_image.reshape((-1, 1))
pixel_values = np.float32(pixel_values)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 3
attempts=10
ret,label,center=cv2.kmeans(pixel_values,K,None,criteria,attempts,cv2.KMEANS_PP_CENTERS)

centers = np.uint8(center)
segmented_data = centers[label.flatten()]
segmented_image = segmented_data.reshape(use_image.shape)

plt.figure(figsize=(10, 6))
plt.subplot(1,2,1),plt.imshow(use_image[:,:,::-1])
plt.title("RGB View")
plt.subplot(1,2,2),plt.imshow(segmented_image[:,:,[2,1,0]])
plt.title(f"Kmean Segmented Image K={K}")

[Python-CVImage Segmentation : Canny Edges, Watershed, and K-Means Methods
透過這些調(diào)整,可以準確分割更多區(qū)域,並最大限度地減少雜訊偽影。

分水嶺演算法在需要精確邊界劃分和重疊物件分離的場景中表現(xiàn)出色。透過利用預處理技術,它甚至可以有效地處理像古墳古墳區(qū)域這樣的複雜圖像。然而,它的成功取決於仔細的參數(shù)調(diào)整和預處理。

結(jié)論

分割是影像分析中的重要工具,提供了隔離和理解影像中不同元素的途徑。本教學展示了三種強大的分割技術:Canny 邊緣偵測、K 均值聚類和分水嶺演算法,每種技術都是針對特定應用程式量身定制的。從勾勒出大阪古古墳的輪廓,到聚類城市景觀和劃分不同區(qū)域,這些方法凸顯了 OpenCV 在應對現(xiàn)實世界挑戰(zhàn)方面的多功能性。

現(xiàn)在去將其中的一些方法應用到您選擇的應用程式中,並發(fā)表評論並分享結(jié)果。另外,如果您知道任何其他簡單的分割方法,也請分享

以上是[Python-CV影像分割:Canny邊緣、分水嶺和K-Means方法的詳細內(nèi)容。更多資訊請關注PHP中文網(wǎng)其他相關文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權的內(nèi)容,請聯(lián)絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Python的UNITDEST或PYTEST框架如何促進自動測試? Python的UNITDEST或PYTEST框架如何促進自動測試? Jun 19, 2025 am 01:10 AM

Python的unittest和pytest是兩種廣泛使用的測試框架,它們都簡化了自動化測試的編寫、組織和運行。 1.二者均支持自動發(fā)現(xiàn)測試用例並提供清晰的測試結(jié)構(gòu):unittest通過繼承TestCase類並以test\_開頭的方法定義測試;pytest則更為簡潔,只需以test\_開頭的函數(shù)即可。 2.它們都內(nèi)置斷言支持:unittest提供assertEqual、assertTrue等方法,而pytest使用增強版的assert語句,能自動顯示失敗詳情。 3.均具備處理測試準備與清理的機制:un

如何將Python用於數(shù)據(jù)分析和與Numpy和Pandas等文庫進行操作? 如何將Python用於數(shù)據(jù)分析和與Numpy和Pandas等文庫進行操作? Jun 19, 2025 am 01:04 AM

pythonisidealfordataanalysisionduetonumpyandpandas.1)numpyExccelSatnumericalComputationswithFast,多dimensionalArraysAndRaysAndOrsAndOrsAndOffectorizedOperationsLikenp.sqrt()

什麼是動態(tài)編程技術,如何在Python中使用它們? 什麼是動態(tài)編程技術,如何在Python中使用它們? Jun 20, 2025 am 12:57 AM

動態(tài)規(guī)劃(DP)通過將復雜問題分解為更簡單的子問題並存儲其結(jié)果以避免重複計算,來優(yōu)化求解過程。主要方法有兩種:1.自頂向下(記憶化):遞歸分解問題,使用緩存存儲中間結(jié)果;2.自底向上(表格化):從基礎情況開始迭代構(gòu)建解決方案。適用於需要最大/最小值、最優(yōu)解或存在重疊子問題的場景,如斐波那契數(shù)列、背包問題等。在Python中,可通過裝飾器或數(shù)組實現(xiàn),並應注意識別遞推關係、定義基準情況及優(yōu)化空間複雜度。

如何使用__ITER__和__NEXT __在Python中實現(xiàn)自定義迭代器? 如何使用__ITER__和__NEXT __在Python中實現(xiàn)自定義迭代器? Jun 19, 2025 am 01:12 AM

要實現(xiàn)自定義迭代器,需在類中定義__iter__和__next__方法。 ①__iter__方法返回迭代器對象自身,通常為self,以兼容for循環(huán)等迭代環(huán)境;②__next__方法控制每次迭代的值,返回序列中的下一個元素,當無更多項時應拋出StopIteration異常;③需正確跟蹤狀態(tài)並設置終止條件,避免無限循環(huán);④可封裝複雜邏輯如文件行過濾,同時注意資源清理與內(nèi)存管理;⑤對簡單邏輯可考慮使用生成器函數(shù)yield替代,但需結(jié)合具體場景選擇合適方式。

Python編程語言及其生態(tài)系統(tǒng)的新興趨勢或未來方向是什麼? Python編程語言及其生態(tài)系統(tǒng)的新興趨勢或未來方向是什麼? Jun 19, 2025 am 01:09 AM

Python的未來趨勢包括性能優(yōu)化、更強的類型提示、替代運行時的興起及AI/ML領域的持續(xù)增長。首先,CPython持續(xù)優(yōu)化,通過更快的啟動時間、函數(shù)調(diào)用優(yōu)化及擬議中的整數(shù)操作改進提升性能;其次,類型提示深度集成至語言與工具鏈,增強代碼安全性與開發(fā)體驗;第三,PyScript、Nuitka等替代運行時提供新功能與性能優(yōu)勢;最後,AI與數(shù)據(jù)科學領域持續(xù)擴張,新興庫推動更高效的開發(fā)與集成。這些趨勢表明Python正不斷適應技術變化,保持其領先地位。

如何使用插座在Python中執(zhí)行網(wǎng)絡編程? 如何使用插座在Python中執(zhí)行網(wǎng)絡編程? Jun 20, 2025 am 12:56 AM

Python的socket模塊是網(wǎng)絡編程的基礎,提供低級網(wǎng)絡通信功能,適用於構(gòu)建客戶端和服務器應用。要設置基本TCP服務器,需使用socket.socket()創(chuàng)建對象,綁定地址和端口,調(diào)用.listen()監(jiān)聽連接,並通過.accept()接受客戶端連接。構(gòu)建TCP客戶端需創(chuàng)建socket對像後調(diào)用.connect()連接服務器,再使用.sendall()發(fā)送數(shù)據(jù)和??.recv()接收響應。處理多個客戶端可通過1.線程:每次連接啟動新線程;2.異步I/O:如asyncio庫實現(xiàn)無阻塞通信。注意事

如何在Python中切片列表? 如何在Python中切片列表? Jun 20, 2025 am 12:51 AM

Python列表切片的核心答案是掌握[start:end:step]語法並理解其行為。 1.列表切片的基本格式為list[start:end:step],其中start是起始索引(包含)、end是結(jié)束索引(不包含)、step是步長;2.省略start默認從0開始,省略end默認到末尾,省略step默認為1;3.獲取前n項用my_list[:n],獲取後n項用my_list[-n:];4.使用step可跳過元素,如my_list[::2]取偶數(shù)位,負step值可反轉(zhuǎn)列表;5.常見誤區(qū)包括end索引不

Python類中的多態(tài)性 Python類中的多態(tài)性 Jul 05, 2025 am 02:58 AM

多態(tài)是Python面向?qū)ο缶幊讨械暮诵母拍睿浮耙环N接口,多種實現(xiàn)”,允許統(tǒng)一處理不同類型的對象。 1.多態(tài)通過方法重寫實現(xiàn),子類可重新定義父類方法,如Animal類的speak()方法在Dog和Cat子類中有不同實現(xiàn)。 2.多態(tài)的實際用途包括簡化代碼結(jié)構(gòu)、增強可擴展性,例如圖形繪製程序中統(tǒng)一調(diào)用draw()方法,或遊戲開發(fā)中處理不同角色的共同行為。 3.Python實現(xiàn)多態(tài)需滿足:父類定義方法,子類重寫該方法,但不要求繼承同一父類,只要對象實現(xiàn)相同方法即可,這稱為“鴨子類型”。 4.注意事項包括保持方

See all articles