java - 检测矩形并将图像裁剪成碎片Android OpenCV
问题描述
嗨,我正在使用 Java 开发一个小型 Android 项目,其中一个功能是检测矩形(包含数据)并将图像裁剪成几个不同的图像(取决于图像包含的矩形。)然后将图像存储在内部存储(用于其他过程)。
我是openCV的新手。我还没有做过任何 openCV 项目。有没有人可以帮助我指导我如何实现这一目标?我找到了一些帮助,但它们都在 python 中,我的知识很少。提前致谢。
解决方案
在无数次尝试和错误之后,我找到了检测矩形的解决方案。我仍然需要进行裁剪部分,但这并不难。感谢这篇文章使用 openCv 在 java 中检查轮廓。 这就是我所做的——
public class ProcessesdResult extends AppCompatActivity {
TextView tvProcessedText;
Bitmap image;
String photoPath;
Mat imageMat;
ImageView ProcessedImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OpenCVLoader.initDebug();
setContentView(R.layout.activity_processesd_result);
Intent intenttakeattendance = getIntent();
String fname = intenttakeattendance.getStringExtra("fname");
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root);
photoPath = myDir+"/sams_images/"+ fname;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
image = BitmapFactory.decodeFile(photoPath, options);
ProcessedImage = findViewById(R.id.processedimage);
// tvProcessedText = findViewById(R.id.tvprocessedtext);
//imageProcess(image);
imageCrop(image);
}
public void imageCrop(Bitmap bitmap){
imageMat=new Mat();
Utils.bitmapToMat(bitmap,imageMat);
Mat imgSource=imageMat.clone();
Mat imageHSV = new Mat(imgSource.size(), CvType.CV_8UC4);
Mat imageBlurr = new Mat(imgSource.size(),CvType.CV_8UC4);
Mat imageA = new Mat(imgSource.size(), CvType.CV_32F);
Imgproc.cvtColor(imgSource, imageHSV, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(imageHSV, imageBlurr, new Size(5,5), 0);
Imgproc.adaptiveThreshold(imageBlurr, imageA, 255,Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY,7, 5);
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(imageA, contours, new Mat(), Imgproc.RETR_LIST,Imgproc.CHAIN_APPROX_SIMPLE);
Vector<Mat> rectangles = new Vector<Mat>();
for(int i=0; i< contours.size();i++){
if (Imgproc.contourArea(contours.get(i)) > 50 )
{
Rect rect = Imgproc.boundingRect(contours.get(i));
if ((rect.height > 30 && rect.height < 120) && (rect.width > 120 && rect.width < 500))
{
Rect rec = new Rect(rect.x, rect.y, rect.width, rect.height);
Mat roi = imageMat.submat(rec);
String filename = myDir.toString() + "/" + i + ".png";
Imgcodecs.imwrite(filename, roi);
rectangles.add(new Mat(imgSource, rec));
Imgproc.rectangle(imgSource, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 0, 255));
}
}
}
Bitmap analyzed=Bitmap.createBitmap(imgSource.cols(),imgSource.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(imgSource,analyzed);
saveTempImage(analyzed);
ProcessedImage.setImageBitmap(analyzed);
}
/*------------------------------------ Store Image -------------------------------------------*/
public void saveTempImage(Bitmap bitmap) {
if (isExternalStorageWritable()) {
saveImage(bitmap);
}else{
Toast.makeText(this, "Please provide permission to write on the Storage!", Toast.LENGTH_SHORT).show();
}
}
private void saveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/sams_images");
if (! myDir.exists()){
myDir.mkdir();
// If you require it to make the entire directory path including parents,
// use directory.mkdirs(); here instead.
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmm").format(new Date());
String fname = timeStamp +".jpg";
File file = new File(myDir, fname);
if (file.exists()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/*------------------------------------ ************* -----------------------------------------*/
}
但是还有一个问题。为此,我得到了内部 vontour 和外部轮廓。我尝试使用 RECT_EXTERNAL 但根本没有检测到轮廓..
推荐阅读
- javascript - JavaScript 错误 (Uncaught SyntaxError: Unexpected end of input) 为什么?
- extjs - 选择组合框 extjs 的默认值
- mysql - 导出到 ShipStation 时,WooCommerce 订单中的订单日期显示为 01-01-1970
- c - 从目录中获取具有特定扩展名的文件
- javascript - 在javascript中使用变量填充多维数组
- msbuild - Cake Build 抑制 MSBuild 警告
- r - 桑基图
- python - Python抓取类更改的深层嵌套div
- c++ - 预处理器输出的差异
- php - PHP - foreach 循环中的 mysqli_query