1. 程式人生 > >OpenCv造輪子(三) 滑窗法實現數碼管影象數字分割

OpenCv造輪子(三) 滑窗法實現數碼管影象數字分割

因為做專案要用到這個方法,就用opencv+py實現了一下,很簡單,先灰度二值化影象,統計Y軸畫素點個數,滑窗檢測間斷點就可以:

def split_by_pixel(img):
    img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #otsu大法好!
    ret, img_thresh = cv2.threshold(img_gray, 130, 255, cv2.THRESH_OTSU)
    #cv2.imshow("out", img_thresh)
    h, w = np.shape(img_thresh)
    #print(h, w)
#建立Y軸方向的直方圖 y_hist = [] for i in range(w): cnt = 0 for j in range(h): if img_thresh[j][i] != 0: cnt += 1 y_hist.append(cnt) #print(y_hist) #取眾數減小誤差 mean = np.argmax(np.bincount(y_hist)) #print(mean) # sliding-window algorithm
st = [] en = [] flag = 0 for j in range(w): if flag == 0 and y_hist[j] - mean > mean: st.append(j) flag = 1 if flag == 1 and y_hist[j] - mean <= mean: en.append(j) flag = 0 print(st, en) size = len(st) for
i in range(size): #減小誤差,寬度過小的不要 if en[i] - st[i] < 10 : continue else: tempfile = img[0:,st[i]:en[i]] cv2.imwrite("s_"+str(i*i)+".jpg",tempfile)

這裡談一下為什麼選擇眾數而不是平均數來當作誤差項:因為如果otsu的效果很好的話,數碼管顯示的數字會被完美閾值化,但是還有可能出現邊緣的亮帶,假設亮帶在影象中普遍存在,那麼亮帶的統計值一定是眾數。經過很多張圖片的實驗的結果,證明了假設成立,當然為了不誤判使用了眾數自己當作閾值,這個即使在亮帶明顯斷開的情況下效果也很好。