QQ 1274510382
Wechat JNZ_aming
商业互捧 QQ群538250800
技术搞事 QQ群599020441
技术合作 QQ群152889761
加入我们 QQ群649347320
纪年科技aming
网络安全 ,深度学习,嵌入式,机器强化,生物智能,生命科学。
灰化、
Canny边缘检测、
Hist直方图计算、
Sobel边缘检测、
SEPIA(色调变换)、
ZOOM放大镜、
PIXELIZE像素化
https://blog.csdn.net/u012556077/article/details/79072340
1.在OpenCV中一般都是使用Mat类型来存储图像等矩阵信息,
所以我们可以声明一个Mat对象用来作为实时帧图像的缓存对象:
//缓存相机每帧输入的数据
private Mat mRgba;
对象实例化以及基本属性的设置,包括:长度、宽度和图像类型标志:
public void onCameraViewStarted(int width, int height) {
// TODO Auto-generated method stub
mRgba = new Mat(height, width, CvType.CV_8UC4);
}
对象赋值
/**
* 图像处理都写在此处
*/
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
switch (Cur_State) {
case 1:
//灰化处理
Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA,4);
break;
default:
//显示原图
mRgba = inputFrame.rgba();
break;
}
//返回处理后的结果数据
return mRgba;
}
由于用对象存储图像数据的话,
数据会保存到内存中,所以结束的时候需要进行数据释放,
不然可能导致崩溃:
@Override
public void onCameraViewStopped() {
// TODO Auto-generated method stub
mRgba.release();
}
private Mat mRgba,mTmp; ;
//对象实例化及基本属性的设置,包括长度、宽度和图像类型标志
public void onCameraViewStarted(int width, int height) {
Log.e("Mat","...............4...............");
mRgba = new Mat(height, width, CvType.CV_8UC4);
///
mTmp = new Mat(height, width, CvType.CV_8UC4);
}
//Canny边缘检测 ///二值化
mRgba = inputFrame.rgba();
Imgproc.Canny(inputFrame.gray(), mTmp, 80, 100);
Imgproc.cvtColor(mTmp, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
package com.e.opcv;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.util.Collections;
import java.util.Date;
import java.util.List;
public class MainActivity extends CameraActivity implements CvCameraViewListener2{
private static final String TAG = "OCVSample::Activity";
//opencv接口标志
/**
* CV相机
*/
private CameraBridgeViewBase mOpenCvCameraView;
//缓存相机每帧输入的数据
private Mat mRgba,mTmp; ;
private Button button;
private boolean mIsJavaCamera = true;
private MenuItem mItemSwitchCamera = null;
/**
* 加载OpenCV的回调
* 通过OpenCV管理Android服务,初始化OpenCV
*/
private BaseLoaderCallback mLoaderCallback ;
public MainActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
if(msg.what == 1){
button.performClick();
}
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
// //初始化并设置预览部件 // 初始化CV相机
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
// 设置相机监听
mOpenCvCameraView.setCvCameraViewListener(this);
//拍照按键
button = (Button) findViewById(R.id.deal_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mRgba != null) {
if(!mRgba.empty()) {
Mat inter = new Mat(mRgba.width(), mRgba.height(), CvType.CV_8UC4);
Log.e("Mat","...............1...............");
//将四通道的RGBA转为三通道的BGR,重要!!
Imgproc.cvtColor(mRgba, inter, Imgproc.COLOR_RGBA2BGR);
Log.e("Mat","...............2...............");
File sdDir = null;
//判断是否存在机身内存
boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
if(sdCardExist) {
//获得机身储存根目录
sdDir = Environment.getExternalStorageDirectory();
Log.e("Mat","...............3...............");
}
//将拍摄准确时间作为文件名
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
String filename = sdf.format(new Date());
String savepath=sdDir + "/Pictures/OpenCV/";
File f=new File(savepath);
if(!f.exists()){
f.mkdirs();
}
String filePath = sdDir + "/Pictures/OpenCV/" + filename + ".png";
Log.e("Mat","..............."+filePath+"...............");
//将转化后的BGR矩阵内容写入到文件中
Imgcodecs.imwrite(filePath, inter);
Toast.makeText(MainActivity.this, "图片保存到: "+ filePath, Toast.LENGTH_SHORT).show();
}
}
}
});
// moveTaskToBack(true);
// new test().start();
// 连接到OpenCV的回调
mLoaderCallback = new BaseLoaderCallback(this){
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
}
private class test extends Thread{
@Override
public void run() {
super.run();
while (true){
try {
Thread.sleep(2000);
Log.e("begin","kaishi.........");
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}catch (Exception e){
Log.e("error",e.getMessage());
}
}
}
}
@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume()
{
// 界面加载完成的时候向OpenCV的连接回调发送连接成功的信号
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
super.onResume();
}
@Override
public List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
//对象实例化及基本属性的设置,包括长度、宽度和图像类型标志
public void onCameraViewStarted(int width, int height) {
Log.e("Mat","...............4...............");
mRgba = new Mat(height, width, CvType.CV_8UC4);
///
mTmp = new Mat(height, width, CvType.CV_8UC4);
}
/**图像处理都写在这里!!!**/
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
//灰度
Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA,4);
//Canny边缘检测 ///二值化
mRgba = inputFrame.rgba();
Imgproc.Canny(inputFrame.gray(), mTmp, 80, 100);
Imgproc.cvtColor(mTmp, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
// mRgba = inputFrame.rgba(); //一定要有!!!不然数据保存不进MAT中!!!
//直接返回输入视频预览图的RGB数据并存放在Mat数据中
Log.e("Mat","...............5...............");
return mRgba;
}
@Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
//结束时释放
public void onCameraViewStopped() {
Log.e("Mat","...............6...............");
mRgba.release();
// mTmp.release();
}
}
https://pqpo.me/2017/09/11/opencv-border-recognition/
在取得图像边缘的基础上,
对一些特定的几何形状边缘,
如直线、圆,通过图像霍夫变换把图像从平面坐标空间变换到霍夫坐标空间,
就可以通过求取霍夫空间的局部极大值方法
(其实就是霍夫空间中的曲线交集点),
得到极坐标空间对应参数方程中直线的两个参数(r,θ),
从而计算得到边缘图像中的所有直线(基于平面坐标)的数目与位置。
参考文献:
https://www.jianshu.com/p/ae5b49b4e5a2
https://www.sohu.com/a/279670020_823210
https://www.cnblogs.com/cheermyang/p/5348820.html
https://vimsky.com/examples/detail/java-method-org.opencv.imgproc.Imgproc.HoughLinesP.html
(…霍夫直线检测 Imgproc.HoughLinesP )
http://www.what21.com/sys/view/media_img_1536741795822.html
( 图形图像上的拉普拉斯平滑(Imgproc.line) )
有 膨胀(或扩张)、腐蚀(或侵蚀)、开启、闭合、骨架抽取、极线腐蚀、击中击不中变换、Top-hat变换、颗粒分析、流域变换、形态学梯度等,
其中腐蚀与扩张就是我们今天所有讲的要点。
opencv中对腐蚀和扩张有相对的函数去实现,多用于图像的取噪、分割出独立的图像元素,在图像中连接相邻的元素、寻找图像中明显的极大值或极小值区、求图像的梯度。
————————————————
https://blog.csdn.net/xuyankuanrong/article/details/79145730
( android使用opencv图片腐蚀与扩张 )
https://blog.csdn.net/m1109048058/article/details/76640714
(膨胀与腐蚀)
package com.e.opcv;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.util.Collections;
import java.util.Date;
import java.util.List;
public class MainActivity extends CameraActivity implements CvCameraViewListener2{
private static final String TAG = "OCVSample::Activity";
//opencv接口标志
/**
* CV相机
*/
private CameraBridgeViewBase mOpenCvCameraView;
//缓存相机每帧输入的数据
private Mat mRgba,mTmp;
private Button button;
private boolean mIsJavaCamera = true;
private MenuItem mItemSwitchCamera = null;
/**
* 加载OpenCV的回调
* 通过OpenCV管理Android服务,初始化OpenCV
*/
private BaseLoaderCallback mLoaderCallback ;
public MainActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
if(msg.what == 1){
button.performClick();
}
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
// //初始化并设置预览部件 // 初始化CV相机
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
// 设置相机监听
mOpenCvCameraView.setCvCameraViewListener(this);
//拍照按键
button = (Button) findViewById(R.id.deal_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mRgba != null) {
if(!mRgba.empty()) {
Mat inter = new Mat(mRgba.width(), mRgba.height(), CvType.CV_8UC4);
Log.e("Mat","...............1...............");
//将四通道的RGBA转为三通道的BGR,重要!!
Imgproc.cvtColor(mRgba, inter, Imgproc.COLOR_RGBA2BGR);
Log.e("Mat","...............2...............");
File sdDir = null;
//判断是否存在机身内存
boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
if(sdCardExist) {
//获得机身储存根目录
sdDir = Environment.getExternalStorageDirectory();
Log.e("Mat","...............3...............");
}
//将拍摄准确时间作为文件名
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
String filename = sdf.format(new Date());
String savepath=sdDir + "/Pictures/OpenCV/";
File f=new File(savepath);
if(!f.exists()){
f.mkdirs();
}
String filePath = sdDir + "/Pictures/OpenCV/" + filename + ".png";
Log.e("Mat","..............."+filePath+"...............");
//将转化后的BGR矩阵内容写入到文件中
Imgcodecs.imwrite(filePath, inter);
Toast.makeText(MainActivity.this, "图片保存到: "+ filePath, Toast.LENGTH_SHORT).show();
}
}
}
});
// moveTaskToBack(true);
// new test().start();
// 连接到OpenCV的回调
mLoaderCallback = new BaseLoaderCallback(this){
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
}
private class test extends Thread{
@Override
public void run() {
super.run();
while (true){
try {
Thread.sleep(2000);
Log.e("begin","kaishi.........");
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}catch (Exception e){
Log.e("error",e.getMessage());
}
}
}
}
@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume()
{
// 界面加载完成的时候向OpenCV的连接回调发送连接成功的信号
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
super.onResume();
}
@Override
public List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
//对象实例化及基本属性的设置,包括长度、宽度和图像类型标志
public void onCameraViewStarted(int width, int height) {
Log.e("Mat","...............4...............");
mRgba = new Mat(height, width, CvType.CV_8UC4);
///
mTmp = new Mat(height, width, CvType.CV_8UC4);
}
/**图像处理都写在这里!!!**/
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
//灰度
Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA,4);
//Canny边缘检测 ///二值化
mRgba = inputFrame.rgba();
Imgproc.Canny(inputFrame.gray(), mTmp, 80, 100);
Imgproc.cvtColor(mTmp, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
Mat dilateImage = mRgba.clone();
Mat erodeImage = mRgba.clone();
Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3,3));
//膨胀
Imgproc.dilate(mRgba, dilateImage, element, new Point(-1, -1), 1);
//腐蚀
Imgproc.erode(mRgba, erodeImage, element, new Point(-1, -1), 1);
// mRgba = inputFrame.rgba(); //一定要有!!!不然数据保存不进MAT中!!!
//直接返回输入视频预览图的RGB数据并存放在Mat数据中
Log.e("Mat","...............5...............");
return mRgba;
}
@Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
//结束时释放
public void onCameraViewStopped() {
Log.e("Mat","...............6...............");
mRgba.release();
// mTmp.release();
}
}