05_OpenCv图像线性混合
一.图像的线性混合
dst = alpha*src1 + beta*src2
- beta = 1-alpha
- alpha的取值为:0.01.0之间,同理,beta取值也在0.01.0之间
- gama不取零的情况:dst = alphasrc1 + betasrc2 + gama
二.Opencv Android SDK中图像线性混合的API
Core.addWeighted(src1, alpha, src2, beta, gama, dst);
三.通过遍历Mat实现图像线性混合
Mat srcMat1 = new Mat();
Mat srcMat2 = new Mat();
Utils.bitmapToMat(src1, srcMat1);
Utils.bitmapToMat(src2, srcMat2);
if(srcMat1.cols() != srcMat2.cols() || srcMat1.rows() != srcMat2.rows() || srcMat1.type() != srcMat2.type()) {
throw new RuntimeException("can not blend image src1 and src2");
}
int width = srcMat1.cols();
int height = srcMat1.rows();
int cnum = srcMat1.channels();
Log.d(TAG, cnum + "");
byte[] src1Bgra = new byte[cnum];
byte[] src2Bgra = new byte[cnum];
byte[] dstBgra = new byte[cnum];
Mat dst = new Mat(srcMat1.size(), srcMat1.type());
for(int row=0; row<height; row++) {
for(int col=0; col<width; col++) {
srcMat1.get(row, col, src1Bgra);
srcMat2.get(row, col, src2Bgra);
for(int i=0; i<cnum; i++) {
dstBgra[i] = (byte) (alpha*(src1Bgra[i]&0xff) + beta*(src2Bgra[i]&0xff) + gama);
}
dst.put(row, col, dstBgra);
}
}
Utils.matToBitmap(dst, dstBitmap);
dst.release();
srcMat1.release();
srcMat2.release();
四.通过遍历Bitmap实现图像线性混合
int width = src1.getWidth();
int height = src1.getHeight();
if(src1.getWidth() != src2.getWidth() || src1.getHeight() != src2.getHeight()) {
throw new RuntimeException("can not blend image src1 and src2");
}
int[] pixels1 = new int[width * height];
int[] pixels2 = new int[width * height];
int[] pixels3 = new int[width * height];
src1.getPixels(pixels1, 0, width, 0, 0, width, height);
src2.getPixels(pixels2, 0, width, 0, 0, width, height);
int src1A = 0, src1R = 0, src1G = 0, src1B = 0, src2A = 0, src2R = 0, src2G = 0, src2B = 0, dstA = 0, dstR = 0, dstG = 0, dstB = 0;
for(int i=0; i<pixels1.length; i++) {
int pixel1 = pixels1[i];
int pixel2 = pixels2[i];
src1A = (pixel1 >> 24) & 0xff;
src1R = (pixel1 >> 16) & 0xff;
src1G = (pixel1 >> 8) & 0xff;
src1B = pixel1 & 0xff;
src2A = (pixel2 >> 24) & 0xff;
src2R = (pixel2 >> 16) & 0xff;
src2G = (pixel2 >> 8) & 0xff;
src2B = pixel2 & 0xff;
dstA = (int)(src1A * alpha + src2A * beta + gama);
dstR = (int)(src1R * alpha + src2R * beta + gama);
dstG = (int)(src1G * alpha + src2G * beta + gama);
dstB = (int)(src1B * alpha + src2B * beta + gama);
int pixel3 = ((dstA&0xff) << 24) | ((dstR&0xff) << 16) | ((dstG&0xff) << 8) | (dstB&0xff);
pixels3[i] = pixel3;
}
dstBitmap.setPixels(pixels3, 0, width, 0, 0, width, height);
五.通过Opencv接口实现图像线性混合
Mat srcMat1 = new Mat();
Mat srcMat2 = new Mat();
Utils.bitmapToMat(src1, srcMat1);
Utils.bitmapToMat(src2, srcMat2);
if(srcMat1.cols() != srcMat2.cols() || srcMat1.rows() != srcMat2.rows() || srcMat1.type() != srcMat2.type()) {
throw new RuntimeException("can not blend image src1 and src2");
}
Mat dst = new Mat(srcMat1.size(), srcMat1.type());
Core.addWeighted(srcMat1, alpha, srcMat2, beta, gama, dst);
Utils.matToBitmap(dst, dstBitmap);
dst.release();
srcMat1.release();
srcMat2.release();
六.结果(alpha=0.5, beta=0.5, gama=0.0)
