標籤:vs2013 opencv python 影像處理
快樂蝦
http://blog.csdn.net/lights_joy/
歡迎轉載,但請保留作者資訊
樸素貝葉斯分類演算法是機器學習中十分經典而且應用十分廣泛的演算法,本文嘗試用它進行資料點的分類。
OpenCV裡面的分類器基本都是先訓練,再預測,貝葉斯分類器也不例外。因此我們先產生訓練資料,總共60個點:
# 訓練的點數train_pts = 30# 建立測試的資料點,2類# 以(-1.5, -1.5)為中心rand1 = np.ones((train_pts,2)) * (-2) + np.random.rand(train_pts, 2)print(‘rand1:‘)print(rand1)# 以(1.5, 1.5)為中心rand2 = np.ones((train_pts,2)) + np.random.rand(train_pts, 2)print(‘rand2:‘)print(rand2)# 合并隨機點,得到訓練資料train_data = np.vstack((rand1, rand2))train_data = np.array(train_data, dtype=‘float32‘)train_label = np.vstack( (np.zeros((train_pts,1), dtype=‘int32‘), np.ones((train_pts,1), dtype=‘int32‘)))
接下來就可以用train_data和train_label進行訓練了:
# 訓練bayer = cv2.ml.NormalBayesClassifier_create()ret = bayer.train(train_data, cv2.ml.ROW_SAMPLE, train_label)# 顯示訓練資料plt.figure(1)plt.plot(rand1[:,0], rand1[:,1], ‘o‘)plt.plot(rand2[:,0], rand2[:,1], ‘o‘)
看看用於訓練的點:
在訓練完成後就可以用訓練好的分類器進行預測:
# 測試資料,20個點[-2,2]pt = np.array(np.random.rand(20,2) * 4 - 2, dtype=‘float32‘)(ret, res) = bayer.predict(pt)print("res = ")print(res)# 按label進行分類顯示plt.figure(2)idx = np.hstack((res, res))for i in range(0, 2) : type_data = pt[idx == i] type_data = np.reshape(type_data, (type_data.shape[0] / 2, 2)) plt.plot(type_data[:,0], type_data[:,1], ‘o‘)plt.show()
看看測試資料和分類結果:
在使用此分類器的時候,發現opencv的C++實現代碼中有一個BUG,如果進行predict的測試資料是一個數組而不是一個點,opencv會執行時會停在下述代碼的注釋部分:
float predictProb( InputArray _samples, OutputArray _results, OutputArray _resultsProb, int flags ) const { int value=0; Mat samples = _samples.getMat(), results, resultsProb; int nsamples = samples.rows, nclasses = (int)cls_labels.total(); bool rawOutput = (flags & RAW_OUTPUT) != 0; if( samples.type() != CV_32F || samples.cols != nallvars ) CV_Error( CV_StsBadArg, "The input samples must be 32f matrix with the number of columns = nallvars" );/*有問題的代碼??*/ //if( samples.rows > 1 && _results.needed() ) // CV_Error( CV_StsNullPtr, // "When the number of input samples is >1, the output vector of results must be passed" ); if( _results.needed() ) { _results.create(nsamples, 1, CV_32S); results = _results.getMat(); } else results = Mat(1, 1, CV_32S, &value); if( _resultsProb.needed() ) { _resultsProb.create(nsamples, nclasses, CV_32F); resultsProb = _resultsProb.getMat(); } cv::parallel_for_(cv::Range(0, nsamples), NBPredictBody(c, cov_rotate_mats, inv_eigen_values, avg, samples, var_idx, cls_labels, results, resultsProb, rawOutput)); return (float)value; }
實際上這個判斷條件完全是多餘的,直接去除即可。
??
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Python影像處理(12):貝葉斯分類器