2015-12-05 5 views
5

私はopencvを初心者にしているので、エッジがかなり外れている以外は "ok"と思われるグラブカットを実行することができます。アウト完璧に行われた画像を得るために、私が気づいたもう一つは、色が、私は以下のやや許容に活気を削減したい全体のプロセスは、私のコードエッジリビジョンOpenCV android

private Bitmap backGrndErase() 
{ 

    color = new Scalar(255, 0, 0, 255); 
    dst = new Mat(); 
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.myshirt); 
    Log.d(TAG, "bitmap: " + bitmap.getWidth() + "x" + bitmap.getHeight()); 


    bitmap = ResizeImage.getResizedBitmap(bitmap, calculatePercentage(40, bitmap.getWidth()), calculatePercentage(40, bitmap.getHeight())); 



    bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); 
    Log.d(TAG, "bitmap 8888: " + bitmap.getWidth() + "x" + bitmap.getHeight()); 



    Mat img = new Mat(); 
    Utils.bitmapToMat(bitmap, img); 


    Point p1 = new Point((img.cols()/10), (img.rows()/10)); 
    Point p2 = new Point((img.cols()-img.cols()/10), (img.rows()-img.rows()/10)); 
    Rect rect = new Rect(p1,p2); 

    int border = 20; 
    int border2 = border + border; 
    Rect rect2 = new Rect(border, border, img.cols() - border2, img.rows()-border2); 




    Mat mask = new Mat(); 
    debugger(""+mask.type()); 
    mask.setTo(new Scalar(125)); 
    Mat fgdModel = new Mat(); 
    fgdModel.setTo(new Scalar(255, 255, 255)); 
    Mat bgdModel = new Mat(); 
    bgdModel.setTo(new Scalar(255, 255, 255)); 

    Mat imgC3 = new Mat(); 
    Imgproc.cvtColor(img, imgC3, Imgproc.COLOR_RGBA2RGB); 
    Log.d(TAG, "imgC3: " + imgC3); 
    Log.d(TAG, "Grabcut begins"); 
    Imgproc.grabCut(imgC3, mask, rect2, bgdModel, fgdModel, 2, Imgproc.GC_INIT_WITH_RECT); 
    Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3.0)); 
    //Do Sth 
    Core.compare(mask, source, mask, Core.CMP_EQ); 
    //Do Sth 
    Mat foreground = new Mat(img.size(), CvType.CV_8UC3, new Scalar(255, 255, 255)); 
    img.copyTo(foreground, mask); 
    Imgproc.rectangle(img, p1, p2, color); 

    Mat background = new Mat(); 
    try { 
     background = Utils.loadResource(getApplicationContext(), 
       R.drawable.blackcolor); 
    } catch (IOException e) { 

     e.printStackTrace(); 
    } 
    Mat tmp = new Mat(); 
    Imgproc.resize(background, tmp, img.size()); 

    background = tmp; 

    Mat tempMask = new Mat(foreground.size(), CvType.CV_8UC1, new Scalar(255, 255, 255)); 
    Imgproc.cvtColor(foreground, tempMask, 6/* COLOR_BGR2GRAY */); 


    Mat vals = new Mat(1, 1, CvType.CV_8UC3, new Scalar(0.0)); 
    dst = new Mat(); 
    background.setTo(vals, tempMask); 
    Imgproc.resize(foreground, tmp, mask.size()); 
    foreground = tmp; 
    Core.add(background, foreground, dst, tempMask); 
    Log.d(TAG, "Convert to Bitmap"); 


    //removing blackbaground started 

    Mat tmp2 = new Mat(); 
    Mat alpha = new Mat(); 
    Imgproc.cvtColor(dst, tmp2, Imgproc.COLOR_BGR2GRAY); 
    Imgproc.threshold(tmp2, alpha, 100, 255, Imgproc.THRESH_BINARY); 


    List<Mat> rgb = new ArrayList<Mat>(3); 
    Core.split(dst, rgb); 


    List<Mat> rgba = new ArrayList<Mat>(4); 
    rgba.add(rgb.get(0)); 
    rgba.add(rgb.get(1)); 
    rgba.add(rgb.get(2)); 
    rgba.add(alpha); 
    Core.merge(rgba, dst); 
    Bitmap output = Bitmap.createBitmap(dst.width(), dst.height(), Bitmap.Config.ARGB_8888); 
    Utils.matToBitmap(dst, output); 

    //removing back ended 


    Utils.matToBitmap(dst, bitmap); 



    //release MAT part 
    img.release(); 
    imgC3.release(); 
    mask.release(); 
    fgdModel.release(); 
    bgdModel.release(); 
    alreadyRun = true; 
    return bitmap; 

} 

である私は同じことを掲示した後、明るすぎになりがちですopencvサイトの質問ですが、ここに比べて視聴者が少ないようです画像my output image, if you look you can see that my output is too vibrant and very bad edges

あなたが検出したい場合は210

I tried it on another image and still got the same over vibrant effect

答えて

7

トライアルコードがちょうどあなたの質問の周りにいくつかの可能性を示すために、

#include "opencv2/opencv.hpp" 

using namespace cv; 

int main(int argc, char** argv) 
{ 
Mat src= imread(argv[1]); 
Mat original = src.clone(); 

imshow("source", src); 

src = src + Scalar(40,40,40); // to remove jpeg artifacts 

Mat mask; 
cvtColor(src, mask, COLOR_BGR2GRAY); 

mask = mask < 255; 

add(src,Scalar(0,60,20),src,mask); 

Mat blackbg = Mat::zeros(src.size(),CV_8UC3); 
original.copyTo(blackbg, mask); 

imshow("mask", mask); 
imshow("changed color", src); 
imshow("original image with black background", blackbg); 
waitKey(); 

return 0; 
} 

enter image description hereenter image description hereenter image description here

+0

、これは非常にいいですが、私は、元の色を保持し、どのような背景があることは白ではないことができる方法、私が我慢することができますどのような対策にはpicにしようとすることを確認しますほとんどの色が正確に四角形から外れていますか?そして最後にどの本を使っていますか、私はopencvがこの良いことを想像したことはありません。 –

+0

チャンスは私のすべてのイメージのためのものです。背景は常に単一の色ですが、おそらく赤や濃い赤です –

+0

更新されたコードを試してください。他のbgの色について考えさせてください。 – sturkmen

0

(背景と仮定すると、常に白になります)エッジやコーナーは非常に正確にopencvは、サブピクセル解像度のツールを設定しており、エッジ検出の前にgaussianFilterを適用することをお勧めしますいくつかの望ましくないノイズを消去します。

+0

ほとんどのコードを更新しました。ここに新しいスレッドがありますhttp://stackoverflow.com/questions/33977051/opencv-increasing-accuracy-of-threshold –

0

このコードを試してください。それは私のために働いて

public Bitmap removeBackground(Bitmap bitmap) { 
 
    //GrabCut part 
 
    Mat img = new Mat(); 
 
    Utils.bitmapToMat(bitmap, img); 
 

 
    int r = img.rows(); 
 
    int c = img.cols(); 
 
    Point p1 = new Point(c/100, r/100); 
 
    Point p2 = new Point(c - c/100, r - r/100); 
 
    Rect rect = new Rect(p1, p2); 
 

 
    Mat mask = new Mat(); 
 
    Mat fgdModel = new Mat(); 
 
    Mat bgdModel = new Mat(); 
 

 
    Mat imgC3 = new Mat(); 
 
    Imgproc.cvtColor(img, imgC3, Imgproc.COLOR_RGBA2RGB); 
 

 
    Imgproc.grabCut(imgC3, mask, rect, bgdModel, fgdModel, 5, Imgproc. 
 
      GC_INIT_WITH_RECT); 
 

 
    Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3.0)); 
 
    Core.compare(mask, source/* GC_PR_FGD */, mask, Core.CMP_EQ); 
 

 
    //This is important. You must use Scalar(255,255, 255,255), not Scalar(255,255,255) 
 
    Mat foreground = new Mat(img.size(), CvType.CV_8UC3, new Scalar(255, 
 
      255, 255,255)); 
 
    img.copyTo(foreground, mask); 
 

 
    // convert matrix to output bitmap 
 
    bitmap = Bitmap.createBitmap((int) foreground.size().width, 
 
      (int) foreground.size().height, 
 
      Bitmap.Config.ARGB_8888); 
 
    Utils.matToBitmap(foreground, bitmap); 
 
    return bitmap; 
 
}