Opencv 4 android常用変換(二)

6304 ワード

Opencv 4 android常用変換(二)
これはopencv 4 androidの第2編で、前の書いた反響はいいですが、少し少ないです.もともと前の編で述べた関数は前の編で紹介したはずですが、その二国間フィルタに頭が混乱して、そんなにたくさん書いて、この編は前の編に続きます.
画像ピラミッド
1つの画像ピラミッドは、一連の画像の集合であり、すべての画像が同じ元の画像に由来する-ある終了条件に達するまでサンプリングを停止するために、ステップダウンサンプリングによって得られる.2つのタイプの画像ピラミッドは、文献およびアプリケーションでよく使用されます.ガウスピラミッド(Gaussian pyramid):ラプラスピラミッドを下にサンプリングするために使用されます.ピラミッドの低層画像から上層の未サンプリング画像を再構築するために使用されます.このドキュメントでは、ガウスピラミッドを使用します.–Opencvチュートリアルに進みます.画像ピラミッドは画像の拡大と縮小を実現する方法の一つであることが明らかになった.Androidで画像の拡大と縮小を実現するには多くの方法がありますが、ここでは様々な実現方法の長所と短所を考慮せずにopencvでスケーリング画像を実現する方法を学びましょう.使用する関数:pyrDown(Mat src, Mat dst, Size dstsize)pyrUp(Mat src, Mat dst, Size dstsize)、ほぼ同じように見えますが、メソッド名が異なります.パラメータ:元の画像、出力画像、出力のサイズです.なぜここのsizeがカーネルではなく出力後のサイズなのか理解できません.全体コード:
//    
private void changeBitmap() {
    if(rgbMat==null|dstMat==null){
    rgbMat=new Mat();
    dstMat=new Mat();
    Utils.bitmapToMat(mBitmap,rgbMat);
    }
    Imgproc.pyrDown(rgbMat,dstMat,new Size(rgbMat.cols()/2,rgbMat.rows()/2));
    rgbMat=dstMat;
    Utils.matToBitmap(dstMat,dstBitmap);
    mImage.setImageBitmap(dstBitmap);
}
//    
private void grayBitmap(){
    if(rgbMat==null|dstMat==null){
        rgbMat=new Mat();
        dstMat=new Mat();
        Utils.bitmapToMat(mBitmap,rgbMat);
    }
    Imgproc.pyrUp(rgbMat,dstMat,new Size(mBitmap.getWidth(),mBitmap.getHeight()));
    Utils.matToBitmap(dstMat,mBitmap);
    mImage.setImageBitmap(mBitmap);
}

ここで画像のスケーリングを行う際に注意すべき点は2つありますが、私のコードでは縮小した後に原画像を縮小した後の画像に設定しています.これはマイクロレッスンで複数回スケーリングした後の効果が見られます.2つ目はbitmapについて、opencvチュートリアルコードの例ではMatオブジェクトを直接画像に表示することができますが、Androidではそうはいきませんので、MatオブジェクトをBitmapオブジェクトに変換する必要があります.このように縮小する過程で問題が発生し、BitmapのサイズがMatのサイズと一致しないとエラーが報告されるので、私のコードではdstBitmapが初期化時にmBitmapの半分のサイズであることにも注意が必要です.効果図:
複数回クリックして縮小すると画像の解像度が著しく低下することがわかる.△私が拭くと、どうして歌詞も入ってきたの?まあ、そうしましょう.みんなも何の歌か当ててみてください.
単純なしきい値操作
最も簡単な画像分割の方法.
適用例:1つの画像からしきい値を用いて私たちが必要とする物体部分を分割する(もちろん、ここでの物体は一部または全体であってもよい).このような画像分割方法は、画像中の物体と背景との階調差に基づいており、この分割は画素レベルの分割に属する.
1つの画像から必要な部分を抽出するためには、画像中の各画素点の階調値を選択した閾値と比較し、対応する判断を行うべきである.(注意:しきい値の選択は、特定の問題に依存します.すなわち、物体が異なる画像で異なる階調値を持つ可能性があります.
分割が必要な物体の画素点が見つかったら、これらの画素点に特定の値を設定して表すことができます.(例えば、物体の画素点の階調値を「0」(黒)、その他の画素点の階調値を「255」(白)、もちろん画素点の階調値は任意であるが、設定した2色のコントラストが強く、結果の観察が容易であることが望ましい).
以上はopencvチュートリアルから来ました.使用する関数:Imgproc.threshold(rgbMat,dstMat,n,255,operation);パラメータ:原画像、出力画像、しきい値サイズ、設定された最大階調値(このパラメータはバイナリと逆バイナリしきい値操作に用いられる)、しきい値方式.しきい値化についてはopencvチュートリアルで5つ紹介されています:-バイナリしきい値化CV_THRESH_BINARY 0-逆バイナリしきい値化CV_THRESH_BINARY_INV 1-カットオフしきい値化CV_THRESH_TRUNC 2-しきい値化0 CV_THRESH_TOZERO 3-逆閾値化0 CV_THRESH_TOZERO_INV 4
どのように調整してもそろっていないようですが、まあ、全部でこの5つのしきい値化方式で、真ん中はandroidの定数で、後ろは対応するint値です.コード~~~~~~:
 private void changeBitmap() {
    if(rgbMat==null|dstMat==null){
    rgbMat=new Mat();
    dstMat=new Mat();
    }
    Utils.bitmapToMat(grayBitmap,rgbMat);
    Imgproc.threshold(rgbMat,dstMat,n,255,operation);
    Utils.matToBitmap(dstMat,dstBitmap);
    dstImage.setImageBitmap(dstBitmap);
}

このコードの前に階調マップに変換してから閾値化して、はっきり見えるようにして、階調化したコードは書かないで、とても簡単で、閾値化も簡単ですが、関数を呼び出すだけで、次は効果図です.
よく見ると、前の2つは反対で、後の2つも反対で、時には紫と緑が現れてなぜか分からないことがあります.opencvを専門に勉強して教えを求めています.
独自のリニアフィルタを実現
Opencvの方がいいと思っていたのですが、書いてあるだけで疲れますよね、と書いてありましたが、言い出すと水をかけるので、続けましょう.フィルタは前に私のブログを見て理解すべきで、opencvの中でも私たちにいくつかの成熟したフィルタを提供して、今私たちは業務の需要のため、自分で1つ書くことができて、使う方法はfilter 2 Dです.
やり方が間違っているようですが、まずコードをつけるべきです.
Mat kernel=Imgproc.getStructuringElement(shape,new Size(2*n+1,2*n+1),new Point(n,n));
    Imgproc.filter2D(rgbMat,dstMat,-1,kernel);

今回は簡単に書きますが、まずカーネルオブジェクトを作成し、前に見たようにfilter 2 D()を呼び出す方法です.パラメータは簡単に紹介して、前の2つは言わないで、3つ目は画像の深さを指して、画像を学ぶのではありませんてよく分かりません、-1は元の画像の深さと同じで、4つ目はカーネルで、その後の他の重荷重の方法の中でアンカーの位置があって、まだ2つあって、最後の1つは繰り返しの回数で、残りのそれはよく理解していないで、ボリュームの過程の中で、この値は各画素の上で加算しますと言います.デフォルトでは、この値は0です.詳細についてはopencvチュートリアルを参照してください.
画像に境界を追加
Opencv 4 androidにはこの方法はないと思っていたが,Sobel導関数で発見された画像に境界を付加するこの方法であった.やはりCoreをよく研究しなければならないようですね.コード:
 Utils.bitmapToMat(mBitmap,rgbMat);
    Core.copyMakeBorder(rgbMat,dstMat,10,10,10,10,Core.BORDER_CONSTANT,new Scalar(255,0,0));
    Log.d("TAG",dstMat.rows()+"/"+dstMat.cols()+"/"+mBitmap.getWidth()+"/"+mBitmap.getHeight());
    Log.d("TAG","dst:"+dstBitmap.getWidth()+"/"+dstBitmap.getHeight());
    Utils.matToBitmap(dstMat,dstBitmap);
    dstImage.setImageBitmap(dstBitmap);

一つの簡単な方法copyMakeBorder()の8つのパラメータは、最初の6つはそれぞれ元の画像、目標画像、上下左右の幅、7つ目は境界充填方式で、2つあり、もう1つはCore.BORDER_CONSTANTの下、最後はスタイルで、私は赤いのを選びました.簡単な問題だと思っていたが、エラーを報告していたが、後で検証してみたところ、マトリクスによって境界が大きくなったときに私たちのBitmapオブジェクトが大きくなっていなかったため、Logによってマトリクスが元の611から631に変わったのに対し、dstBitmapは611だったので、エラーを報告し続け、作成時に20を加えればよかった!あとは、Mat変換時に対応するBitmapの大きさが合っているかどうか、前回は拡大・縮小した時に一度損をしたので、記憶力が落ちないように注意しましょう!
Sobel導関数
Sobel演算子は離散微分演算子(discrete differentiation operator)である.画像階調関数の近似勾配を計算するために使用します.
Sobel演算子はGauss平滑化と微分導出を組み合わせた.
 if(rgbMat==null|dstMat==null){
    rgbMat=new Mat();
    dstMat=new Mat();
    }
    Mat gray=new Mat();//   
    Mat abs_grayx=new Mat();//   X    
    Mat abs_grayy=new Mat();//   Y    
    Utils.bitmapToMat(mBitmap,rgbMat);
    Imgproc.GaussianBlur(rgbMat,rgbMat,new Size(3,3),0,0);
    Imgproc.cvtColor(rgbMat,gray,Imgproc.COLOR_BGR2GRAY);
    Imgproc.Sobel(gray,abs_grayx,-1,1,0,3);//X    ,-1   ,1     
    Imgproc.Sobel(gray,abs_grayy,-1,0,1,3);//Y    ,-1   ,1     
    Core.addWeighted(abs_grayx,0.5,abs_grayy,0.5,0,dstMat);//    
    Utils.matToBitmap(dstMat,dstBitmap);
    dstImage.setImageBitmap(dstBitmap);
}

効果を見てください.
Opencvチュートリアルでの効果.
基本的には同じ(くだらない話、アルゴリズムは同じ)ですが、最初はSobel関数を呼び出すときにImgprocという中でaddWeightedという方法が見つからないと思って、そのままSobelでXY方向の導数をすべて1に設定しましたが、走っても問題ありません.輪郭が細すぎて少なすぎます.その後Coreコアで試してみましたが、マージの方法を見つけてopencvチュートリアルの例に従って書きます.効果はいいですが、Sobelは物体の輪郭を検出するのに役立つでしょう.今まで私が書いたものが何の役に立つか分かりませんでした.
まとめ
Opencv 4 androidの内容はすでに2編書いてありますが、このように書くのが遅すぎることに気づきました.これは8つしか書いていません.しかもImgprocだけで17個もあります.そして、他のモジュールもあります.私は必ず書きます.これは何の役に立つか分かりませんが、次の書くのは簡単でざらざらしているかもしれません.直接方法コードの画像です.できるだけスピードを上げます.まだそんなに多くのものが学んで、そんなに多くの未知が探求を待っていて、墨跡ができません.次のImgprocはまだ17個準備しています8個1編9個1編残りの4、5個の大きなモジュールはまだ見ていません.具体的に決めてから、全体的に20編のブログがないと思います.