/**
* @brief Bitmap效果器
* @author join
*/
public
static
class
Effector {
private
Config config;
private
Mat mat;
private
boolean
isGray;
private
Mat mSepiaKernel;
/**
* @brief 构造函数
* @param bmp 源Bitmap
* @param config 'ARGB_8888' or 'RGB_565'
*/
public
Effector(Bitmap bmp, Config config) {
Mat mat_bmp =
new
Mat(bmp.getHeight(), bmp.getWidth(), CvType.CV_8UC4);
Utils.bitmapToMat(bmp, mat_bmp,
false
);
this
.mat = mat_bmp;
this
.config = config;
this
.isGray =
false
;
}
/**
* @brief 构造函数,config默认为RGB_565
* @see #BitmapUtil(Bitmap, Config)
*/
public
Effector(Bitmap bmp) {
this
(bmp, Bitmap.Config.RGB_565);
}
/**
* @brief 创建Bitmap
* @return Bitmap
*/
public
Bitmap create() {
Mat mat_new =
this
.mat;
if
(isGray) {
Mat mat_gray =
new
Mat(mat_new.rows(), mat_new.cols(), CvType.CV_8UC4);
Imgproc.cvtColor(mat_new, mat_gray, Imgproc.COLOR_GRAY2BGRA,
4
);
mat_new = mat_gray;
}
Bitmap bmp_new = Bitmap.createBitmap(mat_new.cols(), mat_new.rows(),
this
.config);
Utils.matToBitmap(mat_new, bmp_new,
false
);
return
bmp_new;
}
/**
* @brief 灰度化Bitmap
*/
public
Effector gray() {
Mat mat_bmp =
this
.mat;
Mat mat_gray =
new
Mat();
Imgproc.cvtColor(mat_bmp, mat_gray, Imgproc.COLOR_BGRA2GRAY,
1
);
this
.mat = mat_gray;
this
.isGray =
true
;
return
this
;
}
/**
* @brief Bitmap二值化
* @pre 需先灰度化{@link #gray()}
* @param thresh 阈值。type为THRESH_OTSU时无用,其自适应区域阈值。
* @param maxval 最大值。type为THRESH_BINARY或THRESH_BINARY_INV时才使用。
* @param type 运算类型
* @see Imgproc#threshold(Mat, Mat, double, double, int)
* @see THRESH_OTSU: {@link Imgproc#adaptiveThreshold(Mat, Mat, double, int, int, int, double)}
*/
public
Effector threshold(
double
thresh,
double
maxval,
int
type) {
if
(!isGray) {
gray();
}
Mat mat_gray =
this
.mat;
Imgproc.threshold(mat_gray, mat_gray, thresh, maxval, type);
return
this
;
}
/**
* @brief Bitmap二值化
* @details thresh: 127; maxval: 255; type: THRESH_OTSU;
* @see #threshold(double, double, int)
*/
public
Effector threshold() {
return
threshold(
127
,
255
, Imgproc.THRESH_OTSU);
}
/**
* @brief Canny算子边缘检测
* @param threshold1 控制边缘连接的下限阈值
* @param threshold2 控制强边缘的初始分割的上阈限值
* 如果一个像素的梯度大于上阈限值,则被认为是边缘像素,如果小于下限阈值,则被抛弃。
* 如果该点的梯度在两者之间则当这个点与高于上阈限值的像素点连接时我们才保留,否则抛弃。
*/
public
Effector canny(
final
double
threshold1,
final
double
threshold2) {
Mat mat =
this
.mat;
Imgproc.Canny(mat, mat, threshold1, threshold2,
3
,
false
);
return
this
;
}
/**
* @brief Canny边缘检测,返回为RGB_565
* @details threshold1: 80; threshold2: 90;
* @see #canny(Bitmap, Config)
*/
public
Effector canny() {
return
canny(
80
,
90
);
}
/**
* @brief Sobel处理
*/
public
Effector sobel() {
Mat mat =
this
.mat;
Imgproc.Sobel(mat, mat, CvType.CV_8U,
1
,
1
);
Core.convertScaleAbs(mat, mat,
10
,
0
);
return
this
;
}
/**
* @brief 棕褐色
*/
public
Effector sepia() {
Mat mat =
this
.mat;
Core.transform(mat, mat, getSepiaKernel());
return
this
;
}
private
Mat getSepiaKernel() {
if
(mSepiaKernel !=
null
) {
return
mSepiaKernel;
}
mSepiaKernel =
new
Mat(
4
,
4
, CvType.CV_32F);
mSepiaKernel.put(
0
,
0
,
0
.000f,
0
.000f,
0
.000f, 1f);
return
mSepiaKernel;
}
}