一,java代码,收集Bitmap 信息
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btnProc;
private ImageView imageView;
private Bitmap bmp;
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
btnProc = (Button) findViewById(R.id.btn_gray_process);
imageView = (ImageView) findViewById(R.id.image_view);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.test7);
imageView.setImageBitmap(bmp);
btnProc.setOnClickListener(this);
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public static native int[] grayProc(int[] pixels, int w, int h);
@Override
public void onClick(View view) {
int w = bmp.getWidth();
int h = bmp.getHeight();
int[] pixels = new int[w*h];
bmp.getPixels(pixels, 0, w, 0, 0, w, h);
long startTime = System.currentTimeMillis();
int[] resultInt = grayProc(pixels, w, h);
long endTime = System.currentTimeMillis();
w = h = 256;
Log.e("JNITime",""+(endTime-startTime));
Bitmap resultImg = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
//(@ColorInt int[] pixels, int offset, int stride,int x, int y, int width, int height)
resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);
imageView.setImageBitmap(resultImg);
}
}
二,jni实现
using namespace std;
using namespace cv;
void printMAtMessage(Mat &mat);
extern “C”
JNIEXPORT jintArray JNICALL
Java_com_example_dgxq008_opencv_1readpixel_MainActivity_grayProc(JNIEnv *env, jclass type
, jintArray pixels_
, jint w
, jint h) {
jint* pixels = env->GetIntArrayElements(pixels_, NULL);
if (pixels==NULL){
return 0;
}
//图片一进来时是ARGB 通过mat转换BGRA
Mat img(h,w,CV_8UC4,(uchar *)pixels); //pixels 操作的是同一份数据
Mat temp;
//转化为单通道灰度图,并打印信息
cvtColor(img,temp,COLOR_RGBA2GRAY);
const int channels = 0;
const int histSize = 256;
const float hranges[2]={0,255};
const float* ranges[1]={hranges};
//Mat特指2维矩阵,MatND是多维矩阵(>=3维);
MatND hist;
// ( const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist,
//int dims, const int* histSize,const float** ranges, bool uniform = true, bool accumulate = false );
calcHist(&temp, 1, &channels, Mat(), hist, 1, &histSize, ranges);
//打印MatND 信息
printMAtMessage(hist);
double maxVal=0;
double minVal=0;
//找到直方图中的最大值和最小值
//(InputArray src, CV_OUT double* minVal,CV_OUT double* maxVal = 0, CV_OUT Point* minLoc =
// 0,CV_OUT Point* maxLoc = 0, InputArray mask = noArray());
minMaxLoc(hist,&minVal,&maxVal,0,0);
int histSiz=hist.rows;
Mat histImg(histSiz,histSiz,CV_8U,Scalar(255));
// 设置最高点为nbins的90%
int hpt = static_cast<int>(0.9 * histSiz);
LOGD("histSiz.histSiz %d",histSiz);
for(int h=0;h<histSiz;h++)
{
float binVal=hist.at<float>(h);
int intensity=static_cast<int>(binVal * hpt / maxVal);
//打印出信息
LOGD("mat.rows %d",histSiz-intensity);
line(histImg,Point(h,histSiz),Point(h,histSiz-intensity),Scalar::all(0));
}
Mat resizeImage;
cvtColor(histImg,resizeImage,COLOR_GRAY2RGBA);
uchar* datas = resizeImage.data;
//对应数据指针
int size = 256*256;
jintArray result = env->NewIntArray(size);
//env->SetIntArrayRegion(result,0,size,pixels);
env->SetIntArrayRegion(result, 0, size, (const jint *) datas);
env->ReleaseIntArrayElements(pixels_, pixels, 0);
return result;
}
void printMAtMessage(Mat &mat) {
LOGD(“***************************Mat信息开始************************”);
LOGD(“mat.rows %d”,mat.rows);
LOGD(“mat.cols %d”,mat.cols);
LOGD(“mat.total %d”,mat.total());
LOGD(“mat.channels %d”,mat.channels());
LOGD(“mat.depth %d”,mat.depth());
LOGD(“mat.type %d”,mat.type());
LOGD(“mat.flags %d”,mat.flags);
LOGD(“mat.elemSize %d”,mat.elemSize());
LOGD(“mat.elemSize1 %d”,mat.elemSize1());
LOGD(“***************************Mat信息结束************************”);
}
三,效果图
灰度直方图