我正在使用open cv库为android创建过滤器,但它显示了我附加完整代码和快照的匿名结果。
结果图像如下:
原始图片如:
过滤器正在运行,但黑线不是我想要创建的结果。
Xml代码是:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="10dp"
android:layout_height="10dp" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
</RelativeLayout>
MainActivity.java
private native int filter(int width, int height, int [] mPhotoIntArray,int [] nPhotoIntArray, int [] mCannyOutArray);
static {
System.loadLibrary("opencv");
}
ImageView img1;
ImageView img2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img1=(ImageView) findViewById(R.id.imageView1);
img2=(ImageView) findViewById(R.id.imageView2);
InputStream is;
is = this.getResources().openRawResource(R.drawable.filter_image);
Bitmap bmInImg = BitmapFactory.decodeStream(is);
int [] mPhotoIntArray;
int [] nPhotoIntArray;
int [] mCannyOutArray;
mPhotoIntArray = new int[bmInImg.getWidth() * bmInImg.getHeight()];
// Copy pixel data from the Bitmap into the 'intArray' array
bmInImg.getPixels(mPhotoIntArray, 0, bmInImg.getWidth(), 0, 0, bmInImg.getWidth(), bmInImg.getHeight());
// create dummy buffer
nPhotoIntArray = new int[bmInImg.getWidth() * bmInImg.getHeight()];
//create result buffer
mCannyOutArray = new int[bmInImg.getWidth() * bmInImg.getHeight()];
filter(bmInImg.getHeight(), bmInImg.getWidth(), mPhotoIntArray, nPhotoIntArray,mCannyOutArray);
//
// Convert the result to Bitmap
//
Bitmap bmOutImg = Bitmap.createBitmap(bmInImg.getWidth(), bmInImg.getHeight(), Config.ARGB_8888);
bmOutImg.setPixels(mCannyOutArray, 0, bmInImg.getWidth(), 0, 0, bmInImg.getWidth(), bmInImg.getHeight());
storeImage(bmOutImg, "Filter.PNG");
img2.setImageBitmap(bmOutImg);
}
OpenCvFilters.cpp
#include <jni.h>
#include <stdio.h>
#include "opencv2/core/core.hpp"
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
void blending_Lighten(Mat&img,Mat&ing, Mat &out);
extern "C" {
JNIEXPORT jint JNICALL Java_com_example_opencvfilters_MainActivity_filter(
JNIEnv* env, jobject, jint width, jint height, jintArray in,jintArray inn,
jintArray out) {
jint* _in = env->GetIntArrayElements(in, 0);
jint* _inn = env->GetIntArrayElements(inn, 0);
jint* _out = env->GetIntArrayElements(out, 0);
Mat mSrc(height, width, CV_8UC4, (unsigned char*) _in); // for input image
Mat nSrc(height, width, CV_8UC4, (unsigned char*) _inn);
Mat bgra(height, width, CV_8UC4, (unsigned char*) _out);
blending_Lighten(mSrc,nSrc, bgra);
jint retVal;
int ret = 1;
retVal = jint(retVal);
return retVal;
}
}
void blending_Lighten(Mat& img1, Mat& img2, Mat& out)
{
cv::Mat result(img1.size(), CV_32FC4); // result image is same size of input image
// Img2 is the value of solid colors
img2 = Mat(img1.size(), img1.type());
vector<Mat> colors;
split(img2, colors);//bgra
colors[0] = 186;
colors[1] = 44;
colors[2] = 28;
merge(colors, img2);
// Iterate through rows , cols and colors(image channels)
for (int i = 0; i < img1.rows; ++i){
for (int j = 0; j < img1.cols; ++j){
for (int c = 0; c<img1.channels(); c++){ // Iterate through colors
//uchar target = img1.at<uchar>(i, 3*j+c);
//uchar blend = img2.at<uchar>(i, 3*j+c);
//Formula for lighten blending
float target = float(img1.at<uchar>(i, 3 * j + c)) / 255.;
float blend = float(img2.at<uchar>(i, 3 * j + c)) / 255.;
result.at<float>(i, 3 * j + c) = max(target, blend);
}
}
}
result.convertTo(out, CV_8UC4, 255);
}
这是我完整且正常工作的代码,我只想删除图像上的黑线。
答案 0 :(得分:4)
您的图片是四个频道。这意味着你的索引是错误的。在blending_Lighten()
float target = float(img1.at<uchar>(i, 3 * j + c)) / 255.;
float blend = float(img2.at<uchar>(i, 3 * j + c)) / 255.;
result.at<float>(i, 3 * j + c) = max(target, blend);
应该是
float target = float(img1.at<uchar>(i, 4 * j + c)) / 255.;
float blend = float(img2.at<uchar>(i, 4 * j + c)) / 255.;
result.at<float>(i, 4 * j + c) = max(target, blend);
顺便说一句,你没有用颜色设置alpha通道。
并且,似乎blending_Lighten()
可以很好地简化:
void blending_Lighten(Mat& img1, Mat& img2, Mat& out)
{
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 0));
max(img1, img2, out);
}
最后,在从Java_com_example_opencvfilters_MainActivity_filter()
返回之前,您应该致电env->ReleaseIntArrayElements()
,查看您呼叫GetIntArrayElements()
的所有内容。