# 影像辨識太陽能光電模組
###### tags: `Python` `OpenCV`
今天的測試是拿昨天(1/7)的資料來跑一次自己寫的Module,以下做紀錄。
## Demo
總模組數量為單晶722片、多晶760片,共1482片。

## Code
```python=
import cv2 #導入OpenCV
import numpy as np
image = cv2.imread("C:/Users/user/Desktop/0108/New.jpg") #讀取你要的照片檔案(位置)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #對照片進行灰階
#glass = cv2.GaussianBlur(gray,(5,5),0) #對照片進行5x5的高斯模糊化
#若將照片高斯模糊化會影響之後負片轉換時雜訊增加,所以在此不使用
black = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)[1] #將照片進行負片處理
strong = cv2.adaptiveThreshold(black, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 25, 10) #加強負片效果
element = cv2.getStructuringElement(cv2.MORPH_OPEN,(3,3))
dst = cv2.morphologyEx(strong,cv2.MORPH_CLOSE,element) #將照片中的物品腐蝕之後再生長,增加照片板塊的辨識度
(contours,_) = cv2.findContours(dst, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) #尋找邊框
a=0 #模板數量
perilist=[];
for cont in contours:
peri = cv2.arcLength(cont,True) #計算物件的周長
INTperi=int(peri) #轉換型態
perilist.append(INTperi) #將計算的周長增加至列舉裡
maxlabel = max(perilist,key = perilist.count) #計算眾數
for cont in contours:
peri = cv2.arcLength(cont,True) #再計算一次
INTperi=int(peri)
perilist.append(INTperi)
approx = cv2.approxPolyDP(cont,0.06*peri,True) #利用周常計算出圖形有幾個邊
(x,y,w,h)=cv2.boundingRect(approx) #尋找邊的座標
#if int(len(approx)) == 4 : #當圖形的邊有四個(長方形)時做下列的運算
if INTperi < (300*1.2) and INTperi > (300*0.8) : #當在眾數範圍內做下列的運算
cv2.drawContours(image,[cont],-1,(240,0,159),1) #繪製邊框
a=a+1 #計算總共多少塊模板
cv2.putText(image,str(a),(x,y+10),cv2.FONT_HERSHEY_SIMPLEX,0.3,(255,255,255),1) #利用座標將數量之值放置在圖片左上方
cv2.imshow("black",black) #顯示二值化的效果
cv2.imshow("dst",dst) #顯示蝕刻與增長效果
cv2.imshow("image",image) #顯示原圖
print(perilist) #顯示所有週長
print(a) #顯示模板數量
```
## 第一次測試
### 設定參數
- <font color="#f00">不使用</font>高斯模糊
- cv2.threshold(gray,<font color="#f00">125</font>,255,THRESH_BINARY)
- 條件為眾數+-20%(出現最多的數字)
### 成果
**總片數:63片**
從下面的照片能看從二值化的部分就已經有許多特徵消失,在閥值的設定值錯誤,需要從該處做調整。
#### 二值化

#### 侵蝕與增長

#### 結果

## 第二次測試
### 設定參數
- <font color="#f00">不使用</font>高斯模糊
- cv2.threshold(gray,<font color="#f00">200</font>,255,THRESH_BINARY)
- 條件為眾數+-20%(出現最多的數字)
### 成果
**總片數:4644片**
經過這次的測試,由於發現在計算週長時有太多值為0,導致我會執法繪製出圖形,所以我新增條件式
```python=
if INTperi != 0: #當圖形不為0時
perilist.append(INTperi)#將計算的周長增加至列舉裡
```
從這次的試驗中,可以看出在二值化以及侵蝕增長的照片表現很好,但還是有些地方沒有那麼漂亮,而且在尋找太陽能板的判斷式就顯得不是那麼優,需要從該處做調整。
而且最最重要的一點,執行速度太慢了!!!!
#### 二值化

#### 侵蝕與增長

#### 結果

## 第三次測試
### 設定參數
- <font color="#f00">使用</font>高斯模糊
- cv2.threshold(gray,<font color="#f00">180</font>,255,THRESH_BINARY)
- 條件為眾數+-20%(出現最多的數字)
### 成果
**總片數:194片**
在這次的試驗中,我將閥值降低,但原先不明顯的部分直接不見了,顯然想要將照片的清晰度提升需要將閥值增加,待會可以再做測試,使不使用高斯模糊在這次的試驗中並不會影響結果,並且我發現經過侵蝕與增長之後的照片或許不適合做判斷,下一次測試會使用二值化的照片直接做使用,來驗證上述之假設是否正確。
#### 二值化

#### 侵蝕與增長

#### 結果

## 第四次測試
### 設定參數
- <font color="#f00">使用</font>高斯模糊
- cv2.threshold(gray,<font color="#f00">220</font>,255,THRESH_BINARY)
- 條件為眾數+-20%(出現最多的數字)
- 使用<font color="#f00">二值化</font>的照片做判斷
### 成果
**總片數:222片**
在這次的測試中,我將閥值提得太高,全部變成一堆黑,在設定閥值時需要多加測試才能得到最好的標準照片。
#### 二值化

#### 結果

## 第四次測試
### 設定參數
- <font color="#f00">使用</font>高斯模糊
- cv2.threshold(gray,<font color="#f00">210</font>,255,THRESH_BINARY)
- 條件為眾數+-20%(出現最多的數字)
- 使用<font color="#f00">二值化</font>的照片做判斷
### 成果
**總片數:189片**
從這次的實驗來看,將閥值設定在200時的效果會最好。
#### 二值化

#### 結果

## 第五次測試
### 設定參數
- <font color="#f00">使用</font>高斯模糊
- cv2.threshold(gray,<font color="#f00">180</font>,255,THRESH_BINARY_INV)
- 條件為<font color="#f00">週長為158</font>+-20%且為四邊形
- 使用<font color="#f00">二值化</font>的照片做判斷
### 成果
這是成果最好的一次,幾乎所有的太陽能板都能數到,除了中間下面的太陽能以及右上角的區域有點問題之外,其他的表現都相當好。
然而這次的成果會這麼好的原因,是因為我們從圖看到週長範圍大約在150~160之間,但從程式的角度不應該是如此,需要程式自己能夠找到週長為何,是需要再探討的問題。
增加幾個城市是否能將雜訊去除,提高計算的精確度。
**總片數:1530片**
**準確率:96.86%**
#### 結果

#### 週長分布

## 第六次測試
### 設定參數
這次的測試我想要將照片分割成多張,這樣能先將雜訊去除掉,從單一的照片去看成效如何
- <font color="#f00">使用</font>高斯模糊
- cv2.threshold(gray,<font color="#f00">180</font>,255,THRESH_BINARY_INV)
- 條件為條件為眾數+-20%(出現最多的數字)且為四邊形
- 使用<font color="#f00">二值化</font>的照片做判斷
- 分割照片
### 分割效果

### 成果
**總片數:1480片**
**準確率:99.86%**
#### 第一部分
**片數:607片**

#### 第二部分
**片數:399片**

#### 第三部分
**片數:200片**

#### 第四部分
**片數:114片**

#### 第四部分
**片數:160片**
