gpt4 book ai didi

c++ - Opencv 过滤器结果图像上有黑色衬里

转载 作者:搜寻专家 更新时间:2023-10-31 01:03:48 25 4
gpt4 key购买 nike

我正在使用开放式 cv 库为 android 创建过滤器,但它显示匿名结果我附上了我的完整代码和快照。

结果图像如下:

enter image description here

原图是这样的:

enter image description here

过滤器正在工作,但黑线不是我想要创建的结果。

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>

主事件.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);
}

这是我完整的工作代码,我只想删除图像上的黑色衬里。

最佳答案

您的图像是四 channel 的。这意味着您的索引是错误的。在 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 channel 。

而且,似乎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() 的事情.

关于c++ - Opencv 过滤器结果图像上有黑色衬里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25218438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com