欢迎大家来到IT世界,在知识的湖畔探索吧!
今天我们将制作一个Android应用程序,在OpenCV的帮助下将图像转换为铅笔素描。在我们开始之前:我假设您的android项目中已经安装了Open CV。
步骤1:打开activity_main。添加一个ImageView和3个按钮(第一个按钮用于从手机图库中选择图像,另两个按钮用于将图像转换为素描和彩色素描。
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:layout_marginRight="10dp"> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@mipmap/ic_launcher" android:layout_above="@id/btn_contain" android:layout_marginBottom="10dp"/> <LinearLayout android:id="@+id/btn_contain" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="40dp"> <Button android:id="@+id/select_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Select Image "/> <Button android:id="@+id/sketch" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sketch"/> <Button android:id="@+id/colored_sketch" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Colored Sketch"/> </LinearLayout> </RelativeLayout>
欢迎大家来到IT世界,在知识的湖畔探索吧!
步骤2:打开MainActivity.java,再onCreate中添加如下java代码。
欢迎大家来到IT世界,在知识的湖畔探索吧!private ImageView image; private Button select, sketch, colored @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); OpenCVLoader.initDebug(); image = findViewById(R.id.image); select = findViewById(R.id.select_img); sketch = findViewById(R.id.sketch); colored = findViewById(R.id.colored_sketch); }
步骤3:创建一个ImageChooser函数,从图库中选择图像并显示在ImageView中。
为图像选择器声明几个变量。
private final int SELECT_PHOTO = 1; private Bitmap originBitmap = null; private File tempFile = new File("/sdcard/a.jpg"); private Bitmap processImg;
显示图像选择器的函数
欢迎大家来到IT世界,在知识的湖畔探索吧!private void showImageChooser() { Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); photoPickerIntent.setType("image/*"); startActivityForResult(photoPickerIntent, SELECT_PHOTO); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == SELECT_PHOTO && resultCode == RESULT_OK && null != data) { Uri selectedImage = data.getData(); InputStream imageStream; try { imageStream = getContentResolver().openInputStream(selectedImage); originBitmap = BitmapFactory.decodeStream(imageStream); } catch (FileNotFoundException e) { e.printStackTrace(); } if (originBitmap != null) { tempFile.delete(); this.image.setImageBitmap(originBitmap); } } }
将OnClickListener设置为图像选择按钮
select.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { showImageChooser(); } });
步骤4:让我们将效果应用到选定的图像。
为了将图像转换为素描,我们需要制作3个不同的图像层
- 灰度(第1层)
- 反转灰度图像(第2层)
- 将高斯模糊应用于inverted image(第3层)
- 用于铅笔素描的颜色减淡和混合(第3层,第1层),用于彩色素描的颜色减淡(原始图像,第1层)。
素描函数的java代码如下:
public void Sketch(Bitmap bitmap, String type){ bitmap=bitmap.copy(Bitmap.Config.ARGB_8888, true); Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4); Mat dest = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4); Mat grey = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4); Mat invert = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4); Bitmap inv, gray; Utils.bitmapToMat(bitmap, src); Imgproc.cvtColor(src, grey, Imgproc.COLOR_BGR2GRAY); Imgproc.cvtColor(grey, grey, Imgproc.COLOR_GRAY2RGBA, 4); Core.bitwise_not( grey, invert); Imgproc.GaussianBlur(invert,invert, new Size(11,11),0); inv = Bitmap.createBitmap(invert.cols(),invert.rows(),Bitmap.Config.ARGB_8888); gray = Bitmap.createBitmap(invert.cols(),invert.rows(),Bitmap.Config.ARGB_8888); Utils.matToBitmap(invert, inv); Utils.matToBitmap(grey, gray); Bitmap b = null; if (type.equals("normal")) { b = ColorDodgeBlend(inv, gray); }else if(type.equals("colored")){ b = ColorDodgeBlend(inv, bitmap); } processImg = Bitmap.createBitmap(dest.cols(),dest.rows(),Bitmap.Config.ARGB_8888); Utils.matToBitmap(dest, processImg); image.setImageBitmap(b); }
颜色减淡和混合的java代码:
private static int colordodge(int in1, int in2) { float image = (float)in2; float mask = (float)in1; return ((int) ((image == 255) ? image:Math.min(255, (((long)mask << 8 ) / (255 - image))))); } public static Bitmap ColorDodgeBlend(Bitmap source, Bitmap layer) { Bitmap base = source.copy(Bitmap.Config.ARGB_8888, true); Bitmap blend = layer.copy(Bitmap.Config.ARGB_8888, false); IntBuffer buffBase = IntBuffer.allocate(base.getWidth() * base.getHeight()); base.copyPixelsToBuffer(buffBase); buffBase.rewind(); IntBuffer buffBlend = IntBuffer.allocate(blend.getWidth() * blend.getHeight()); blend.copyPixelsToBuffer(buffBlend); buffBlend.rewind(); IntBuffer buffOut = IntBuffer.allocate(base.getWidth() * base.getHeight()); buffOut.rewind(); while (buffOut.position() < buffOut.limit()) { int filterInt = buffBlend.get(); int srcInt = buffBase.get(); int redValueFilter = Color.red(filterInt); int greenValueFilter = Color.green(filterInt); int blueValueFilter = Color.blue(filterInt); int redValueSrc = Color.red(srcInt); int greenValueSrc = Color.green(srcInt); int blueValueSrc = Color.blue(srcInt); int redValueFinal = colordodge(redValueFilter, redValueSrc); int greenValueFinal = colordodge(greenValueFilter, greenValueSrc); int blueValueFinal = colordodge(blueValueFilter, blueValueSrc); int pixel = Color.argb(255, redValueFinal, greenValueFinal, blueValueFinal); buffOut.put(pixel); } buffOut.rewind(); base.copyPixelsFromBuffer(buffOut); blend.recycle(); return base; }
将OnClickListener添加到按钮
sketch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (originBitmap != null) { Sketch(originBitmap, "normal"); } } }); colored.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (originBitmap != null) { Sketch(originBitmap, "colored"); } } });
步骤5:在模拟器中构建和测试应用程序。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/23003.html