Android OpenCV集成摄像头图片动态识别车牌号
最近兩天開發一個使用OpenCV集成的一個識別車牌號的項目,困難重重,總結一下相關經驗,以及開發注意事項;
一、開發環境:
Android Studio 個人版本 3.1.4
NDK下載:14b
CMake:Android Studio SDK Tools中下載
參考資料:https://github.com/zeusees/HyperLPR 集成有沖突未解決;
很實用的一個Dmeo以這個為例
https://blog.csdn.net/u011686167/article/details/79029765
樓主人很好,給我解答疑問;附上博主Demo下載地址:
https://download.csdn.net/download/u011686167/10899892
集成中遇到的問題:
一、環境配置的問題:
NDK:嘗試使用最新版本,但是一直有沖突,出現問題,14b使用兼容性比較好
CMake:
OpenCV類庫: openCVLibrary330
二、項目集成問題:
(1)下載模型文件替換和倒入assets/pr下面的文件,報錯如下:
"/storage/emulated/0/pr/HorizonalFinemapping.prototxt") in bool cv::dnn::ReadProtoFromTextFile(
const char*,google::protobuf::Message*), file /build/master_pack-android/opencv/modules/dnn/src
/caffe/caffe_io.cpp, line 1113
(2)添加攝像頭權限
(3)問題:只能橫向識別車牌號,縱向不能識別,并且相機方向不對:
解決相機顯示正常:
參考資料 https://blog.csdn.net/u010112268/article/details/80420454
將下圖文件中的deliverAndDrawFrame方法
修改為以下:
protected void deliverAndDrawFrame(CvCameraViewFrame frame){
Mat modified;
if (mListener != null) {
modified = mListener.onCameraFrame(frame);
} else {
modified = frame.rgba();
}
boolean bmpValid = true;
if (modified!= null) {
try {
Utils.matToBitmap(modified,mCacheBitmap);
} catch(Exceptione) {
Log.e(TAG, "Mattype: " + modified);
Log.e(TAG, "Bitmaptype: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight());
Log.e(TAG, "Utils.matToBitmap()throws an exception: " +e.getMessage());
bmpValid = false;
}
}
if (bmpValid&& mCacheBitmap != null) {
Canvas canvas =getHolder().lockCanvas();
if (canvas!= null) {
canvas.drawColor(0,android.graphics.PorterDuff.Mode.CLEAR);
/*if (BuildConfig.DEBUG)
Log.d(TAG, "mStretchvalue: " + mScale);
if (mScale != 0) {
canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(),mCacheBitmap.getHeight()),
newRect((int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2),
(int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2),
(int)((canvas.getWidth() -mScale*mCacheBitmap.getWidth()) / 2 + mScale*mCacheBitmap.getWidth()),
(int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2 +mScale*mCacheBitmap.getHeight())), null);
} else {
canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(),mCacheBitmap.getHeight()),
newRect((canvas.getWidth() - mCacheBitmap.getWidth()) / 2,
(canvas.getHeight()- mCacheBitmap.getHeight()) / 2,
(canvas.getWidth() -mCacheBitmap.getWidth()) / 2 + mCacheBitmap.getWidth(),
(canvas.getHeight()- mCacheBitmap.getHeight()) / 2 + mCacheBitmap.getHeight()), null);
}*/
/*----------------------------修改預覽旋轉90度問題--------------------------------*/
canvas.rotate(90,0,0);
float scale= canvas.getWidth() / (float)mCacheBitmap.getHeight();
float scale2= canvas.getHeight() / (float)mCacheBitmap.getWidth();
if(scale2> scale){
scale = scale2;
}
if (scale!= 0) {
canvas.scale(scale,scale,0,0);
}
canvas.drawBitmap(mCacheBitmap, 0, -mCacheBitmap.getHeight(), null);
/*----------------------------修改預覽旋轉90度問題--------------------------------*/
if (mFpsMeter != null) {
mFpsMeter.measure();
mFpsMeter.draw(canvas, 20, 30);
}
getHolder().unlockCanvasAndPost(canvas);
}
}
}
解決圖片不能縱向識別方法:參考資料https://blog.csdn.net/hujiameihuxu/article/details/78810100
圖片角度轉換:
Mat matRotateClockWise90(Mat src)
{
if (src.empty())
{
qDebug()<<"RorateMat src is empty!";
}
// 矩陣轉置
transpose(src, src);
//0: 沿X軸翻轉; >0: 沿Y軸翻轉; <0: 沿X軸和Y軸翻轉
flip(src, src, 1);// 翻轉模式,flipCode == 0垂直翻轉(沿X軸翻轉),flipCode>0水平翻轉(沿Y軸翻轉),flipCode<0水平垂直翻轉(先沿X軸翻轉,再沿Y軸翻轉,等價于旋轉180°)
return src;
}
Mat matRotateClockWise180(Mat src)//順時針180
{
if (src.empty())
{
qDebug() << "RorateMat src is empty!";
}
//0: 沿X軸翻轉; >0: 沿Y軸翻轉; <0: 沿X軸和Y軸翻轉
flip(src, src, 0);// 翻轉模式,flipCode == 0垂直翻轉(沿X軸翻轉),flipCode>0水平翻轉(沿Y軸翻轉),flipCode<0水平垂直翻轉(先沿X軸翻轉,再沿Y軸翻轉,等價于旋轉180°)
flip(src, src, 1);
return src;
//transpose(src, src);// 矩陣轉置
}
Mat matRotateClockWise270(Mat src)//順時針270
{
if (src.empty())
{
qDebug() << "RorateMat src is empty!";
}
// 矩陣轉置
//transpose(src, src);
//0: 沿X軸翻轉; >0: 沿Y軸翻轉; <0: 沿X軸和Y軸翻轉
transpose(src, src);// 翻轉模式,flipCode == 0垂直翻轉(沿X軸翻轉),flipCode>0水平翻轉(沿Y軸翻轉),flipCode<0水平垂直翻轉(先沿X軸翻轉,再沿Y軸翻轉,等價于旋轉180°)
flip(src, src, 0);
return src;
}
Mat myRotateAntiClockWise90(Mat src)//逆時針90°
{
if (src.empty())
{
qDebug()<<"mat is empty!";
}
transpose(src, src);
flip(src, src, 0);
進行轉化:
本人Demo代碼地址以及模型地址:https://gitee.com/anan9303/PrjAndroid.git
總結
以上是生活随笔為你收集整理的Android OpenCV集成摄像头图片动态识别车牌号的全部內容,希望文章能夠幫你解決所遇到的問題。