北科資工二多媒體技術與應用 第三周作業-辨識硬幣種類

筆記說明

此筆記用途在於台北科技大學資訊工程系大二下多媒體技術與應用作業紀錄
並非所有人都適用,部分對我而言稍加容易的內容並不會寫在此內。
這是學習後心得的筆記,可能不太適用會未來的學生

由於我沒有學習過裡面的理論,因此這是資工大二學生透過網路與自身理解的筆記,學習價值並不高、且可能擁有大量錯誤。

題目如下,用圖片

此題作法

此題與北科資工二多媒體技術與應用 第三周作業-辨識硬幣與鈔票種類大部分相同。
不一樣的部分是此題判斷硬幣是用長度來判斷,因為硬幣長寬都會相同。

考倒我了,嗚嗚。
我對於圖學的知識過少,還需要增加自己對於多媒體的思考能力R。

由於此題已經有告訴你需要用的步驟與規則如下

  • 二值化 cv2.threshold
    給予一數值 x,圖片中大於 x 的點都變成白色,小於的則變成黑色
  • 膨脹 cv2.dilate
    先給予一個矩陣,如果此矩陣裡有白色的點,那所有點都變為白色,要搭配二值化此用
  • 侵蝕 cv2.erode
    先給予一個矩陣,如果此矩陣裡有白色的點,那所有點都變為黑色,要搭配二值化此用
  • 連通物件 cv2.connectedComponentsWithStatsconnectivity=4 時表示判斷區塊的方式是上下左右,connectivity=4 時是上下左右加上左上、左下、右下、右上。
    幫你找出圖片中的所有白色區塊,會給出四個回傳值。
    • num_labels 有多少區塊
    • labels 透過矩陣表示區塊
    • stats 是一個陣列,依序是 x座標、y座標、長、寬、面積,面積以像素為單位
    • centroids 區塊的中心點
  • 圖片大小不可以超過 1000 像素,透過 cv2.resize 進行
  • 對硬幣畫線,透過 ````cv2.rectangle``` 進行

現在我們有了這些資訊,就比較好畫圖了。

將資料統整後,可以得出一個結論

  • 圖片大小不可以超過 1000 像素,所以我們先 cv2.resize
  • 再來進行二值化,因為如果沒有二值化後面所有東西都不能做
    至於要在那個點做 x 化就要不斷嘗試
  • 查看圖片,發現還是有很多白點散布在硬幣的旁邊,因此先侵蝕
    至於要在矩陣多大就要不斷嘗試
  • 侵蝕完畢後,發現硬幣的邊界有點變形,在做膨脹
    至於要在矩陣多大就要不斷嘗試
  • 再來連通物件,print(stat)
    發現有很多圓形,我們先對全部的區塊畫線,檢查有沒有硬幣沒有被畫到,或太偏差,有就在回前幾步重新嘗試
  • 確認沒有後,將每種硬幣畫線
    不斷找出每種硬幣的寬度是多少,以此為依據畫線。
  • 輸出答案

參考連結

提供我所用到的連結
OpenCV中的绘图函数 by OpenCV-Python 中文教程
Error could not find a writer by OpenCV
opencv: 图像缩放(cv2.resize) by JNingWei
How to use openCV’s connected components with stats in python? by stackoverflow
[Python+OpenCV] 畫矩形 rectangle by ShengYu Talk
Orange Color Code by RapidTables

心得

原本在上課老師給的學習時間中不斷嘗試卻一直失敗,果然再不太熟的情況下想要做出一份專案是不可能的壓XD,要先透過別人的資料進行學習,從中得知能做好事的關鍵,然後我們再進行模仿,成功後再進行改良、創新。

謝謝郭梓琳、林紀緯的程式碼,讓我從中學習到這麼多的知識。

放在網路上供我知道,也讓有困難的朋友也能學習到。

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import cv2
import numpy as np

img = cv2.imread("../pic/coin.jpg") #輸入資料
h, w, ch = img.shape #圖片高、寬、通道

img = cv2.resize(img, (w//5, h//5), interpolation=cv2.INTER_NEAREST) #important
#縮小圖片,記住這邊的 interpolation 選擇很重要,如果不確定建議可以都試試找最棒的

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #灰階化,方便閱讀
ret, gray = cv2.threshold(gray, 90, 255, cv2.THRESH_BINARY) #二值化,90 是慢慢設定的

gray = cv2.erode(gray, np.ones((2,2)), iterations=2) #侵蝕,裡面矩陣與 iterations 細調
gray = cv2.dilate(gray, np.ones((2,2)), iterations=1) #膨脹,裡面矩陣與 iterations 細調

#連通物件,設八通道這樣才嚴謹
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(gray, connectivity=8)
print(stats) #檢查所有區塊

ans = 0 #輸出多少錢

for it in stats:
itX = it[0]+it[2] #寬度
itY = it[1]+it[3] #高度
#cv2.rectangle(img, (it[0], it[1]), (itX, itY), (200, 31, 31), 2)
#一開始可以使用,這樣她會畫出所有的區塊來讓你判斷有沒有區塊沒畫到或連在一起

#下面的長度是我自己去慢慢調整出來得
if(it[2] >= 60 and it[2] < 75): #1 dallars
cv2.rectangle(img, (it[0], it[1]), (itX, itY), (0, 0, 255), 2) #BGR
ans += 1
if(it[2] >= 75 and it[2] < 90): #5 dallars
cv2.rectangle(img, (it[0], it[1]), (itX, itY), (0, 165, 255), 2) #BGR
ans += 5
if(it[2] >= 90 and it[2] < 100): #10 dallars
cv2.rectangle(img, (it[0], it[1]), (itX, itY), (0, 255, 255), 2) #BGR
ans += 10
if(it[2] >= 100 and it[2] < 115): #50 dallars
cv2.rectangle(img, (it[0], it[1]), (itX, itY), (0, 128, 0), 2) #BGR
ans += 50

#cv2.imshow("gray", gray)
print("圖上共有 ",ans ,"元") #輸出答案
cv2.imshow("img", img)
cv2.imwrite('ans.jpg', img)
cv2.imwrite('gray.jpg', gray)
cv2.waitKey(0)

題目資料

硬幣圖片

灰階、二值化、膨脹、侵蝕後的圖片

答案

  • 版權聲明: 本部落格所有文章除有特別聲明外,均採用 Apache License 2.0 許可協議。轉載請註明出處!
  • © 2020-2024 John Doe
  • Powered by Hexo Theme Ayer
  • PV: UV: