欢迎大家来到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