標籤:reg ret ide scalar 設定 mina 3.3 tps 2.4
小老闆給了新任務,看來要研究一下java的影像處理了。
目前最基本的目標是:任意圖片的文字提取。
還沒有明確的思路,先簡單調研一下看看別人都怎麼搞的吧。
首先是搭環境。
1. 下載安裝opencv。
去opencv官網下載並且解壓縮就好了。目前我還沒搞清版本2.4和3.3有什麼區別。
這裡有的文章說要加path,我就順手加了。$opencvpath$/build/java/x64
2. 在IDEA中建立項目。
這就沒啥說的了,建立一個java項目就可以。
3. 設定jar庫和dll位置。
在project structure中建立一個java庫,然後引用到$opencvpath$/build/java/*.jar
然後在run configurations裡的VM option雷根據opencv庫解壓縮的位置添加:-Djava.library.path=D:\MyLibrary\opencv-3.3.0-vc14\build\java\x64;D:\MyLibrary\opencv-3.3.0-vc14\build\java\x64
最後,在建立的類裡面,一定要包含以下代碼:
static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
然後就可以了…………最後一步大概折騰了我半個小時…………直到看到一篇文章提到這段代碼,我才意識到是少了這個。
然後就是先隨便抓一篇代碼練練手。
這裡參考了這篇文章 http://blog.csdn.net/huobanjishijian/article/details/63685503
然後面臨的問題就是:網上常見的opencv代碼都是用c++或者python實現的。但是目前看要求,我這套還是得在java上跑,所以就需要把代碼改寫成java版本的。
這裡用到了opencv的官方手冊。https://docs.opencv.org/java/2.4.11/
反正就是一條一條對,但是仍然有對不上的。
最後代碼如下:
import org.opencv.core.*;import java.util.ArrayList;import java.util.List;import static org.opencv.core.CvType.CV_8U;import static org.opencv.imgcodecs.Imgcodecs.imread;import static org.opencv.imgcodecs.Imgcodecs.imwrite;import static org.opencv.imgproc.Imgproc.*;/** * Created by wangzhao on 2017/10/24. */public class test { static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } public static void main(String[] args){ System.out.println("hello"); System.out.println(Core.VERSION); Mat mat=imread("test.jpg"); System.out.println(mat); detect(mat); } public static void detect(Mat img) { Mat gray=new Mat(); cvtColor(img, gray, COLOR_BGR2GRAY); Mat pro=preprocess(gray); List<MatOfPoint> region=findTextRegion(pro); System.out.println(region.size()); drawContours(img, region, -1, new Scalar(0, 255, 0), 2); imwrite("contours.png", img); } public static Mat preprocess(Mat gray) { Mat sobel=new Mat(); Sobel(gray, sobel, CV_8U, 1, 0); Mat binary=new Mat(); threshold(sobel, binary, 0, 255, THRESH_OTSU+THRESH_BINARY); Mat element1=getStructuringElement(MORPH_RECT, new Size(30,9)); Mat element2=getStructuringElement(MORPH_RECT, new Size(24,6)); Mat dilation=new Mat(); dilate(binary, dilation, element2); Mat erosion=new Mat(); erode(dilation, erosion, element1); Mat dilation2=new Mat(); dilate(erosion, dilation2, element2); imwrite("binary.png", binary); imwrite("dilation.png", dilation); imwrite("erosion.png", erosion); imwrite("dilation2.png", dilation2); return dilation2; } public static List<MatOfPoint> findTextRegion(Mat img) { Mat hierarchy=new Mat(); List<MatOfPoint> contours=new ArrayList<>(); findContours(img, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);// for (MatOfPoint cnt:contours) {// double area=contourArea(cnt);// if (area<1000) {// continue;// }// double epsilon=0.001*arcLength(new MatOfPoint2f(cnt.toArray()), true);// MatOfPoint2f approx=new MatOfPoint2f();// approxPolyDP(new MatOfPoint2f(cnt.toArray()), approx, epsilon, true);// RotatedRect rect=minAreaRect(new MatOfPoint2f(cnt.toArray()));// } return contours; }}
好訊息是:現在用java跑opencv已經沒有大的問題了。
但是仍然有以下的問題需要解決:
1. 一些c++或python的opencv庫提供的函數,在java中並不存在。對於存在的函數,由於python不需要聲明變數類型,所以改寫成java的版本也效率很低。不過這至少可以work。
2. 這次初步嘗試的文本提取方法,對於稍微複雜一點的情況就無法實現了。需要調研尋找可靠的文字提取演算法。
以上是今天嘗試的收穫。
java opencv 01