好吧所以我是opencv的新手,我已经设法执行一个对我来说似乎"好"的抓取,除了边缘非常变形,我想要获得逼真的边缘,可能会模糊边缘以获得完美的图像,我注意到的另一件事是整个过程后颜色往往太亮了我想减少活力到下面可以接受的是我的代码
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); Listrgb = new ArrayList (3); Core.split(dst, rgb); List rgba = new ArrayList (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网站上发布了同样的问题,但与此处的图像相比,似乎有较低的受众
一个试用代码,只是为了展示你问题的一些可能性(假设背景总是白色的)
#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; }