φυβλαςのβλογ
บล็อกของ phyblas



opencv-python เบื้องต้น บทที่ ๑๑: การวิเคราะห์ฮิสโทแกรมและปรับสมดุลสีภาพ
เขียนเมื่อ 2020/06/28 19:01
แก้ไขล่าสุด 2024/02/22 10:24

ต่อจาก บทที่ ๑๐

บทนี้จะเป็นเรื่องของการวิเคราะห์สีภายในรูปภาพด้วยฮิสโทแกรม และการปรับแปลงสีในรูปภาพโดยพิจารณาจากฮิสโทแกรม รวมถึงการปรับสีโดยการปรับแก้แกมมา




การสร้างฮิสโทแกรมแจกแจงความสว่างของภาพ

ฮิสโทแกรมคือแผนภูมิแท่งที่เอาไว้แจกแจงว่าภายในข้อมูลกลุ่มหนึ่งมีค่าอะไรอยู่ในขอบเขตไหนแค่ไหน

ในด้านการจัดการรูปภาพ ข้อมูลที่ต้องการวิเคราะห์ก็คือค่าความสว่างของภาพ สามารถวาดฮิสโทแกรมเพื่อแจกแจงดูได้ว่ามีค่าความสว่างของสีไหนอยู่ในช่วงไหนมากแค่ไหน

สำหรับภาพสีอาจวาดฮิสโทแกรมแยกดูความสว่างของ ๓ สี หรืออาจเปลี่ยนเป็นภาพขาวดำแล้วดูแค่ความเข้ม

ก่อนอื่นจะเขียนถึงการใช้ฮิสโทแกรมกับภาพขาวดำก่อน จากนั้นช่วงท้ายจึงค่อยมาดูแยกสี

ฟังก์ชันสำหรับสร้างฮิสโทแกรมนั้นมีอยู่ทั้งใน numpy และ matplotlib แต่ในที่นี้จะแนะนำฟังก์ชันสร้างฮิสโทแกรมของใน opencv ซึ่งเหมาะสำหรับใช้งานกับข้อมูลรูปภาพโดยเฉพาะ ฟังก์ชันนั้นคือ cv2.calcHist()

ค่าที่ต้องใส่ในฟังก์ชันมีดังนี้

ลำดับที่ ชื่อ ค่าที่ต้องใส่ ชนิดข้อมูล
1 images อาเรย์รูปภาพ list ของ np.array
2 channels ช่องสีที่จะพิจารณา list ของ int
3 mask อาเรย์ตัวกรอง เมื่อต้องการเฉพาะบางส่วน list ของ np.array
4 histSize จำนวนช่อง list ของ int
5 ranges ขอบเขตค่าที่ต้องการ list ของ int

ค่าทั้งหมดที่ต้องใส่ล้วนใส่ในรูปของลิสต์ แม้ว่าอาเรย์รูปภาพที่จะใช้มีเพียงรูปเดียวก็ให้ใส่ไว้ในลิสต์

สำหรับช่องสีที่จะพิจารณานั้น ในกรณีภาพขาวดำให้ใส่ [0] ไป เพราะไม่มีสีอยู่แล้ว

ตัวกรองมีไว้ใช้เมื่อต้องการพิจารณาแค่บางส่วน ถ้าไม่ใช้ให้ใส่ None ไปได้

จำนวนช่อง ปกติจะใส่ [256] และขอบเขตใส่เป็น [0,256] เนื่องจากภาพมี ๒๕๖ สี

ขอยกตัวอย่างโดยโดยวิเคราะห์ฮิสโทแกรมของภาพนี้ในโหมดขาวดำ


miku11c01.jpg
import cv2
import numpy as np
import matplotlib.pyplot as plt

miku = cv2.imread('miku11c01.jpg',0) # เปิดภาพมาเป็นขาวดำ
plt.figure(figsize=[6,8])
plt.subplot(211) # วาดภาพเดิมแบบขาวดำ
plt.imshow(miku,cmap='gray')
plt.colorbar(pad=0.01)
plt.subplot(212) # วาดฮิสโทแกรม
hist = cv2.calcHist([miku],[0],None,[256],[0,256])
plt.bar(np.arange(256),hist[:,0],1,color='m')
plt.tight_layout()
plt.show()


ได้ฮิสโทแกรมที่แสดงการแจกแจงความสว่างของภาพออกมาดังนี้ จะเห็นว่าในภาพนี้ส่วนใหญ่ค่าความสว่างของภาพจะกองกันอยู่ตรงกลางๆ

ลองคำนวณผลบวกสะสมในอาเรย์ของฮิสโทแกรมโดยใช้ .cumsum()
plt.plot(hist[:,0].cumsum(),'r')
plt.show()


กราฟแสดงค่าผลบวกสะสมนี้จะเป็นตัวพิจารณาสำคัญเพื่อนำมาใช้ในกระบวนการปรับภาพ เช่นพิจารณาปรับค่าผลบวกสะสมให้ขึ้นต่อเนื่องอย่างสม่ำเสมอเป็นเส้นตรง




การนำฮิสโทแกรมมาปรับให้เรียบ

ใน opencv มีฟังก์ชัน cv2.equalizeHist() ซึ่งเอาไว้ปรับรูปภาพให้มีฮิสโทแกรมสะสมในลักษณะที่ราบเรียบ

ฟังก์ชันนี้ใส่แค่ตัวอาเรย์รูปภาพที่ต้องการปรับ แล้วก็จะคืนค่าอาเรย์ผลลัพธ์หลังการปรับมาให้เรียบร้อย

ลองเอาภาพจากตัวอย่างที่แล้วมาปรับเรียบ แล้ววาดภาพที่ได้ใหม่ พร้อมวาดฮิสโทแกรม และค่าผลบวกสะสมดู
miku = cv2.imread('miku11c01.jpg',0)
miku_eql = cv2.equalizeHist(miku)
plt.figure(figsize=[6,12])
plt.subplot(311) # ภาพหลังการปรับ
plt.imshow(miku_eql,cmap='gray')
plt.colorbar(pad=0.01)

plt.subplot(312) # ฮิสโทแกรม
hist_eql = cv2.calcHist([miku_eql],[0],None,[256],[0,256])
plt.bar(np.arange(256),hist_eql[:,0],1,color='m')

plt.subplot(313) # ผลบวกสะสมของฮิสโทแกรม
plt.plot(hist_eql[:,0].cumsum(),'r')

plt.tight_layout()
plt.show()


จะเห็นว่าภาพที่ได้จากการปรับจะมีการแจกแจงของฮิสโทแกรมเปลี่ยนไปจากเดิม โดยจะแจกแจงให้ผลบวกสะสมเรียงกันเป็นค่าเพิ่มสม่ำเสมอ

ผลที่ได้คือภาพที่มีการแจกแจงสีมากกว่าเดิม โดยเห็นตั้งแต่ขาวไปจนดำ ซึ่งการทำแบบนี้มีประโยชน์ตรงที่ทำให้แยกแยะรายละเอียดภายในภาพได้ชัดขึ้น เห็นลวดลายต่างๆเด่นชัด

อย่างไรก็ตาม การที่แค่ปรับเรียบแบบนี้อาจไม่ได้ให้ผลออกมาดีนักเสมอไปในกรณีทั่วไป โดยเฉพาะสำหรับภาพที่มีแสงต่างกันไปมากในแต่ละบริเวณ

ขอยกตัวอย่างเช่นภาพนี้


gumi11c01.jpg

ลองวิเคราะห์ดูฮิสโทแกรม
gumi = cv2.imread('gumi11c01.jpg',0)
plt.figure(figsize=[6,12])
plt.subplot(311) # ภาพเดิม
plt.imshow(gumi,cmap='gray')
plt.colorbar(pad=0.01)

plt.subplot(312) # ฮิสโทแกรม
hist = cv2.calcHist([gumi],[0],None,[256],[0,256])
plt.bar(np.arange(256),hist[:,0],1,color='m')

plt.subplot(313) # ผลบวกสะสม
plt.plot(hist[:,0].cumsum(),'r')

plt.tight_layout()
plt.show()


จะเห็นว่าแจกแจงกระจายไม่สม่ำเสมอยิ่งกว่าภาพแรกอีก โดยมีค่าหนึ่งที่มากเป็นพิเศษ

ลองเอามาปรับเรียบด้วยวิธีเดิม
gumi = cv2.imread('gumi11c01.jpg',0)
gumi_eql = cv2.equalizeHist(gumi)

plt.figure(figsize=[6,12])
plt.subplot(311) # ภาพหลังการปรับ
plt.imshow(gumi_eql,cmap='gray')
plt.colorbar(pad=0.01)

plt.subplot(312) # ฮิสโทแกรม
hist_eql = cv2.calcHist([gumi_eql],[0],None,[256],[0,256])
plt.bar(np.arange(256),hist_eql[:,0],1,color='m')

plt.subplot(313) # ผลบวกสะสม
plt.plot(hist_eql[:,0].cumsum(),'r')

plt.tight_layout()
plt.show()


จะเห็นว่าแปลงแล้วกลับออกมาแปลกๆ ส่วนที่สว่างอยู่แล้วโดนปรับจนสว่างจ้าเกินไป กลับดูเสียสมดุล

และถ้าดูฮิสโทแกรมแล้วจะเห็นว่าแม้จะพยายามปรับให้ผลบวกฮิสโทแกรมดูเรียบ แต่ตรงค่าส่วนที่สูงเด่นโดดๆนั้นก็ทำเสียสมดุลไป

ดังนั้นจึงมีการคิดวิธีการ CLAHE ขึ้นมา ซึ่งใช้งานได้ดีกว่าวิธีเดิมเมื่อเจอกรณีแบบนี้




วิธีการ CLAHE

CLAHE ย่อมาจาก Contrast Limited Adaptive Histogram Equalization คือเป็นวิธีการปรับฮิสโทแกรมในแบบที่ปรับตัวเองได้

จากเดิมปัญหาของวิธี cv2.equalizeHist() ก็คือนำทั้งภาพมาคิดพร้อมๆกัน แบบนั้นเมื่อเจอภาพที่มีความสว่างต่างกันมากในแต่ละบริเวณก็จะดึงถ่วงกันจนเสียสมดุลได้

ดังนั้นควรแยกพิจารณาเป็นบริเวณไปจึงช่วยรักษาสมดุลของภาพหลังแปลงได้ นี่คือหลักการของ CLAHE

วิธีการใช้เริ่มจากสร้างออบเจ็กต์ CLAHE ขึ้นมาโดยฟังก์ชัน cv2.createCLAHE() จากนั้นใช้เมธอด .apply() ที่ตัวรูปภาพที่ต้องการแปลง

ตัวอย่าง ลองเอาภาพเดิมจากตัวอย่างที่แล้วมาปรับด้วยวิธี CLAHE
gumi = cv2.imread('gumi11c01.jpg',0)
clahe = cv2.createCLAHE() # สร้างออบเจ็กต์ CLAHE
gumi_clahe = clahe.apply(gumi) # เริ่มทำการแปลง

plt.figure(figsize=[6,12])
plt.subplot(311)
plt.imshow(gumi_clahe,cmap='gray')
plt.colorbar(pad=0.01)

plt.subplot(312)
hist_clahe = cv2.calcHist([gumi_clahe],[0],None,[256],[0,256])
plt.bar(np.arange(256),hist_clahe[:,0],1,color='m')

plt.subplot(313)
plt.plot(hist_clahe[:,0].cumsum(),'r')

plt.tight_layout()
plt.show()


จะได้ภาพออกมาดูดีกว่าวิธีเดิม ส่วนฮิสโทแกรมก็มีการแจกแจงกระจายดีขึ้น ผลบวกสะสมแม้จะไม่ได้เรียบตรงเสียทีเดียว แต่ก็ทำให้ค่อนข้างเรียบ ในขณะที่รักษาสมดุลสีในแต่ละบริเวณไปด้วย




การใช้ฮิสโทแกรมกับภาพสี

ตัวอย่างที่ผ่านมาเป็นการพิจารณาฮิสโทแกรมของภาพขาวดำโดยดูแค่ความสว่างโดยรวม

สำหรับในส่วนสุดท้ายนี้จะเขียนถึงการพิจารณาแยกสี

ฟังก์ชัน cv2.calcHist() นั้นเมื่อใช้กับภาพขาวดำจะใส่ค่าช่องสี (channels) เป็น [0] เพราะมีสีเดียว แต่ถ้าใช้กับภาพสีอาจใส่ตัวเลข 0,1,2 แล้วแต่ว่าจะวิเคราะห์ช่องไหน

ลองดูตัวอย่าง ใช้วิเคราะห์ภาพสีโดยแยกวาดฮิสโทแกรมของแต่ละสี แต่ใส่ในกราฟเดียวกัน


rin11c01.jpg
rin = cv2.imread('rin11c01.jpg')
plt.figure(figsize=[6,7])
ax1 = plt.subplot(211)
ax2 = plt.subplot(212)
for i,c in enumerate('bgr'):
    hist = cv2.calcHist([rin],[i],None,[256],[0,256])
    ax1.plot(hist,c) # ฮิสโทแกรม
    ax2.plot(hist.cumsum(),c) # ผลบวกสะสม
plt.tight_layout()
plt.show()


ผลที่ได้จะเห็นได้ว่ามีการแจกแจงของสีไหนอยู่ในช่วงไหนมาก

ต่อมาลองวิเคราะห์พร้อมกันทั้ง ๓ สีดู เพื่อจะได้เห็นความสัมพันธ์ระหว่างแต่ละสี โดยค่าจำนวนช่องก็ต้องใส่ 256 ไป ๓ ครั้ง ส่วนช่วงขอบเขตก็ใส่ 0,256 ไป ๓ ครั้งเรียงต่อกัน

ผลลัพธ์ที่ได้จะเป็นอาเรย์ที่มี ๓​ มิติ เพราะมีค่าของสีทั้ง ๓ แต่การแสดงผลของทั้ง ๓​ สีพร้อมกันทีเดียวนั้นทำได้ยาก จึงได้แต่ทำแยกทีละ ๒ สี เช่นแบบนี้
rin = cv2.imread('rin11c01.jpg')
hist = cv2.calcHist([rin],[0,1,2],None,[256,256,256],[0,256,0,256,0,256])
plt.figure(figsize=[6,15])

# น้ำเงิน-เขียว
plt.subplot(311,xlabel='b',ylabel='g')
plt.imshow(hist.sum(2),cmap='coolwarm')
plt.colorbar(pad=0.01)
# น้ำเงิน-แดง
plt.subplot(312,xlabel='b',ylabel='r')
plt.imshow(hist.sum(1),cmap='coolwarm')
plt.colorbar(pad=0.01)
# เขียว-แดง
plt.subplot(313,xlabel='g',ylabel='r')
plt.imshow(hist.sum(0),cmap='coolwarm')
plt.colorbar(pad=0.01)

plt.tight_layout()
plt.show()


ผลที่ได้ดูแล้วจะเห็นว่าคู่สีไหนมีสีอยู่ในช่วงไหนมากเป็นพิเศษ จะมีค่าสูงเด่นขึ้นมา

แต่ค่าต่างกันมากแบบนี้ทำให้ดูค่าส่วนสีอื่นที่มีบ้างเล็กน้อยได้ยาก เพื่อให้เห็นภาพชัดลองวาดใหม่โดนเปลี่ยนเป็นปรับสัดส่วนเป็นลอการิธึม
import matplotlib as mpl
lognorm = mpl.colors.LogNorm()

plt.figure(figsize=[6,15])
for i,(xl,yl) in enumerate(['bg','br','gr']):
    plt.subplot(311+i,xlabel=xl,ylabel=yl)
    plt.imshow(hist.sum(2-i),cmap='coolwarm',norm=lognorm)
    plt.colorbar(pad=0.01)

plt.tight_layout()
plt.show()


จากนั้นลองมาวิเคราะห์ฮิสโทแกรมของสีในระบบ HSV ดูบ้าง

เราสามารถแปลงภาพเป็น HSV แล้วนำมาวิเคราะห์ได้ในลักษณะเดียวกัน เพียงแต่ส่วนค่า H จะมีค่าแค่ 180 จึงต้องใส่ในฟังก์ชันตามนั้นด้วย
rin = cv2.imread('rin11c01.jpg')
rin_hsv = cv2.cvtColor(rin,cv2.COLOR_BGR2HSV)
hist = cv2.calcHist([rin_hsv],[0,1,2],None,[180,256,256],[0,180,0,256,0,256])
plt.figure(figsize=[6.5,4.5])

plt.subplot(221,title='h-s')
plt.imshow(hist.sum(2),cmap='coolwarm',norm=lognorm)
plt.colorbar(pad=0.01)

plt.subplot(222,title='h')
plt.plot(hist.sum(2).sum(1))
plt.subplot(223,title='s')
plt.plot(hist.sum(2).sum(0))
plt.subplot(224,title='v')
plt.plot(hist.sum(1).sum(0))

plt.tight_layout()
plt.show()





การปรับแก้แกมมา

อีกวิธีหนึ่งที่อาจใช้เพื่อปรับโทนสีโดยรวมของภาพก็คือวิธีการที่เรียกว่าการปรับแก้แกมมา (gamma correction)

วิธีการก็คือเปลี่ยนค่าความสว่างโดนดูจากค่าความสว่างเดิม ตามสมการนี้



โดยค่า γ (แกมมา) เป็นจำนวนบวก ลองวาดกราฟเทียบระหว่างค่าเก่ากับใหม่ที่ค่าแกมมาต่างๆกันดูได้ดังนี้
x = np.arange(256)
gamma = [1/5,1/3,0.5,1,2,3,5]
plt.figure(figsize=[5,5])
plt.axes(aspect=1)
for i,g in enumerate(gamma):
    x_gamma = 255*(x/255)**(1/g)
    plt.plot(x,x_gamma,label='$\gamma=%.2f$'%g,color=plt.get_cmap('rainbow')(i/6))
plt.legend()
plt.show()


กราฟนี้จะเป็นตัวแสดงบอกว่าถ้าเดิมมีความสว่างเท่าไหร่จะกลายเป็นเท่าไหร่ไป

ซึ่งจะเห็นได้ว่าถ้าค่า γ สูงกว่า 1 ภาพโดยรวมจะสว่างขึ้น ถ้า γ=1 ก็จะเท่ากับภาพเดิมไม่มีอะไรเปลี่ยนแปลง ถ้าค่า γ น้อยกว่า 1 ก็จะมืดลง แต่ไม่ว่าจะเปลี่ยนไปยังไง ความสว่างโดยรวมก็จะยังคงอยู่ในช่วง 0 ถึง 255

ในการแปลงแกมมาในรูปภาพเราอาจเอาค่า γ คำนวณแล้วสร้างตารางเทียบเตรียมเอาไว้ก่อน แล้วใช้ฟังก์ชัน cv2.LUT() เพื่อแปลงค่าสีในภาพนั้นตามตาราง

ค่าที่ต้องใส่ในฟังก์ชัน cv2.LUT() คือ

ลำดับที่ ชื่อ ค่าที่ต้องใส่ ชนิดข้อมูล
1 src อาเรย์รูปภาพ np.array
2 lut ตัวเทียบแปลง np.array

ตารางสำหรับแปลงที่ต้องใช้คืออาเรย์ขนาด 256 ซึ่งแทนค่าที่ต้องการแปลงไปตั้งแต่ 0 ถึง 255 ไว้

ลองดูตัวอย่างการนำวิธีการปรับแก้แกมมาเอามาใช้กับรูปภาพ


teto11c01.jpg
teto = cv2.imread('teto11c01.jpg')
gamma = [1/2,2/3,1,1.5,2,3] # ค่าแกมมาที่จะลองใช้
plt.figure(figsize=[6,7])
ar0255 = np.arange(0,256)/255
for i,g in enumerate(gamma):
    plt.subplot(321+i,title='$\gamma=%.2f$'%g,xticks=[],yticks=[])
    # สร้างตัวเทียบแปลงตามค่าแกมมา
    lut = (255*ar0255**(1/g)).astype(np.uint8)
    # แปลงสีตามตัวเทียบแปลงที่เตรียมไว้
    teto_gamma = cv2.LUT(teto,lut)
    plt.imshow(teto_gamma[:,:,::-1])
plt.tight_layout(0)
plt.show()


สุดท้ายลองเทียบฮิสโทแกรมของภาพที่ได้จากการปรับดู
plt.figure(figsize=[6,7])
for i,g in enumerate(gamma):
    teto_gamma = 255*(teto/255)**(1/g)
    plt.subplot(321+i,title='$\gamma=%.2f$'%g)
    for j,c in enumerate('bgr'):
        hist = cv2.calcHist([teto_gamma],[j],None,[256],[0,256])
        plt.plot(hist,c) # ฮิสโทแกรม
plt.tight_layout(0)
plt.show()





อ่านบทถัดไป >> บทที่ ๑๒



-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> opencv
-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> numpy
-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> matplotlib

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
ภาษา javascript
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文