2016-11-03 10:31:40 u012042963 阅读数 2913

最近想研究利用Hadoop处理图像问题,利用Hadoop的高并行性解决图像处理效率低下的问题。初始就先利用别人的开源项目进行试验,于是找到了github上的图像处理开源项目mipr,但是在使用的过程中出了很多问题。于是将问题记录如下,以供其他童鞋参考。

首先将源码down下来进行编译,将jar上传并将事先准备好的图像上传到HDFS上。执行Img2Gray对图像进行灰度化,很顺利并且处理的结果也很好。但是当执行/mipr-opencv中的边缘检测程序时就出现了一下问题,如图所示


一直没找到libopencv_java2411.so在哪,后来下载一个放进去死活不行。仍然报同样的错误,后来发现opencvMapper有用到DistributedCache类,才明白必须将libopencv_java2411.so文件放到HDFS上并在main.so文件中进行指定。上传完果然问题解决,可是又出现了如下问题(真是愁人)


个人觉得是因为Linux上opencv版本不对或者没有安装完全所致,继续慢慢寻找原因以及解决的办法。先写到这里等问题解决再追加,欢迎遇到同样问题的童鞋一块交流共同学习。

2019-08-17 23:21:16 weixin_43211480 阅读数 159

一、一定要注意图像数据类型

如果读入是uint8类型,那么一定要转化成double类型,再进行运算

im2double()函数

因为uint8类型会溢出,再大也是255,得不到想要的效果

见博客:MATLAB在做图像处理时为什么有时候先把图像转换为double型?防止计算时溢出用double,而 显示图像的时候用uint8

https://blog.csdn.net/weixin_43740956/article/details/89320146

 

2015-07-13 17:15:21 mikulee 阅读数 1112

NDK 图像处理遇到的相关问题

写在前面的话:
博主最近在学习Android NDK 视频处理相关东西,出现很多诡异问题,记录一下。

文章地址:http://blog.csdn.net/mikulee/article/details/46865139
欢迎转载,请注明出处,谢谢。

1、SEGV_ACCERR
我在一个函数里面创建了一个640*480大小的一维数组,作为图像数据,例如

int testPixels(){
 int len=640*480;
 int pixels[len];
 int index=0;
 for(;index<len;index++){
    pixels[index]=0xffff0000;
 }
return 0;
}

代码没问题,但是在真机上运行的话,会抛出SEGV_ACCERR错误,而且通过堆栈无法定位问题所在。
通过错误日志看出是在数组index达到45000以后,pixels就无法访问了,就会出现SEGV_ACCERR。上网查找资料,无果。怀疑是int的数值范围不够,sizeof(int)=4,是可以容纳640*480数值的。
最后,灵光一现,会不会是函数栈大小的问题。这个应该和编译器或什么有关。所以决定尝试在堆上建立pixels的存储空间,如下面代码:

int* pixels=NULL;
int testPixels(){
int len=640*480;
if(pixels==NULL){
    //这里如果为空,就创建一个。暂时不考虑释放问题。
     pixels=(int*)malloc(len*sizeof(int));
 }
 int index=0;
 for(;index<len;index++){
    pixels[index]=0xffff0000;
 }
return 0;
}

问题得以解决。

2、JNI 中填充bitmap颜色不正确
在网上找了个函数,为YUV转argb的,原文在这里(Android视频渲染: YUV转RGB ),我稍作改动,可以直接填充java传过来的bitmap,以免每次都重复创建,导致app不断GC.但是颜色总是有问题,经多方查究,终于解决。

int g_v_table[256],g_u_table[256],y_table[256];
int r_yv_table[256][256],b_yu_table[256][256];
int inited = 0;
void initTable()
{
    if (inited == 0)
    {
        inited = 1;
        int m = 0,n=0;
        for (; m < 256; m++)
        {
            g_v_table[m] = 833 * (m - 128);
            g_u_table[m] = 400 * (m - 128);
            y_table[m] = 1192 * (m - 16);
        }
        int temp = 0;
        for (m = 0; m < 256; m++)
            for (n = 0; n < 256; n++)
            {
                temp = 1192 * (m - 16) + 1634 * (n - 128);
                if (temp < 0) temp = 0; else if (temp > 262143) temp = 262143;
                r_yv_table[m][n] = temp;

                temp = 1192 * (m - 16) + 2066 * (n - 128);
                if (temp < 0) temp = 0; else if (temp > 262143) temp = 262143;
                b_yu_table[m][n] = temp;
            }
    }
}
jint Java_com_miku_jni_ImageUtilEngine_decodeYUV420SP(JNIEnv * env,
        jobject thiz, jbyteArray buf, jobject bitmap, jint width, jint height) {
    AndroidBitmapInfo info;
    int* pixels = NULL;
    if (AndroidBitmap_getInfo(env, bitmap, &info) >= 0) {
        AndroidBitmap_lockPixels(env, bitmap, (void **) &pixels);
        jbyte * yuv420sp = (*env)->GetByteArrayElements(env, buf, 0);
        int frameSize = width * height;
        initTable();
        int i = 0, j = 0, yp = 0;
        int uvp = 0, u = 0, v = 0;
        for (j = 0, yp = 0; j < height; j++) {
            uvp = frameSize + (j >> 1) * width;
            u = 0;
            v = 0;
            for (i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp]));
                if (y < 0)
                    y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]);
                    u = (0xff & yuv420sp[uvp++]);
                }

                int y1192 = y_table[y];
                int r = r_yv_table[y][v];
                int g = (y1192 - g_v_table[v] - g_u_table[u]);
                int b = b_yu_table[y][u];

                if (g < 0)
                    g = 0;
                else if (g > 262143)
                    g = 262143;
                //原文这里如果直接赋值给bitmap的像素的话就有问题(并不是函数有问题),
                //因为bitmap的数  据是RGBARGBA这样的序列
                //但这里pixels[yp]为整形,数据格式是(小端格式)LittleEndian
                //直接赋值一个整数,例如pixels[yp]=0xff051003(ff为A,05为R,10为G,03为B)的话,
                //在内存中是这样的存储的[031005ff],并不是你直接赋的值[ff051003]。对比[031005ff]
                //和RGBA顺序,03(B)和05(R)的位置刚好倒置了,所以在机器上,显示的颜色就不正确了。
                //pixels[yp] = 0xff000000 | ((r << 6) & 0xff0000)
                //      | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
                //改为下面,颜色即可正确
                pixels[yp] = 0xff000000 | ((b << 6) & 0xff0000)
                        | ((g >> 2) & 0xff00) | ((r >> 10) & 0xff);
            }
        }
        (*env)->ReleaseByteArrayElements(env, buf, yuv420sp, 0);
        AndroidBitmap_unlockPixels(env, bitmap);
    }
    return 1;
}

3、FFmpeg相关
FFmpeg编译可以参考这位大神的编译指南FFmpeg的Android平台移植,我编译的是当前最新的2.7.1版本,按步骤来,能正常编译出各个so库文件。
在我的nexus 5下,使用没任何问题。但在小米4.1系统下,遇到如下的问题:
Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1891]: 150 could not load needed library ‘libswresample-1.so’ for ‘libavcodec-56.so’ (load_library[1093]: Library ‘libswresample-1.so’ not found)。
明明lib目录下是有libswresample-1.so,怎么就说没找到呢。
网上搜索并无真正答案。
最后灵光一现,libswresample-1.so’ for ‘libavcodec-56.so’ 的意思应该是libswresample-1.so必须先于libavcodec-56.so之前加载,其他库也是,有先后顺序之分的。在高版本的android上面没问题,但低版本要注意次序
经过几下尝试,加载顺序如下:

static {
        //先按顺序加ffmpeg动态库
        System.loadLibrary("avutil-54");
        System.loadLibrary("swresample-1");
        System.loadLibrary("avcodec-56");
        System.loadLibrary("swscale-3");
        System.loadLibrary("avformat-56");
        System.loadLibrary("avfilter-5");
        System.loadLibrary("avdevice-56");
        //最后才加载自己写的库
        System.loadLibrary("ffmpegNative");
    }
2019-06-16 22:04:48 weixin_44210987 阅读数 28

0.错误
在这里插入图片描述
首先检查是否添加了这个环境变量
自己的库文件有时候也要检查
在这里插入图片描述

  1. 错误

    1 error LNK2001: 无法解析的外部符号 "public: virtual struct CRuntimeClass * __thiscall PictureDialog::GetRuntimeClass(void)const " (?GetRuntimeClass@PictureDialog@@UBEPAUCRuntimeClass@@XZ) F:\BianCheng\MacthineVision\PorousCharacteristicAnalysis\PorousCharacteristicAnalysis\PictureDialog.obj

解决办法:
<1>,在.h文件中写了DECLARE_DYNAMIC,而在.cpp文件中没有写IMPLEMENT_DYNAMIC
<2>,在.h文件中写了DECLARE_DYNCREATE ,但在.cpp文件中没有写上IMPLEMENT_DYNCREATE

  1. 错误
    错误 1 error LNK2001: 无法解析的外部符号 “protected: virtual void __thiscall PictureDialog::DoDataExchange(class CDataExchange *)” (?DoDataExchange@PictureDialog@@MAEXPAVCDataExchange@@@Z) F:\BianCheng\MacthineVision\PorousCharacteristicAnalysis\PorousCharacteristicAnalysis\PictureDialog.obj

解决办法:
添加两行语句,在这里插入图片描述
3.错误

Opencv出现“_pFirstBlock == pHead”错误的解决方法

解决办法:
整个项目是基于动态库的,所以运行库那儿改成下图
在这里插入图片描述
同时,项目默认值—MFC的使用 改成下图
在这里插入图片描述
4.错误

在计数时报的错
在这里插入图片描述
这一块代码为

    // 将控件中的数据保存到相应的变量   
	UpdateData(TRUE);

	// 将被点数赋值给m_editSummand  
	m_editSummand = contours.size();

	// 根据各变量的值更新相应的控件。和的编辑框会显示m_editSum的值   
	UpdateData(FALSE);

解决办法:
在这里插入图片描述

2017-12-08 23:15:24 weixin_36297465 阅读数 283

python图像处理过程中遇到的坑

使用PIL进行图像的处理:

  • 使用PIL.open()方法打开一张图片,此时图片是一个图像对象,不是numpy数组.
  • 此时这个图像的对象可以进行各种操作, 例如灰度,提高亮度,增强, 调整分辨率等等.
  • 使用np.array功能,可以将一个图像对象转化为np的数组. 然后用于神经网络或者其他的各种操作.
  • 在使用PIL的fromarray功能时候,很可能会遇到bug,提示”格式不支持”.这个时候很有可能是mode没有选择正确.
  • 在使用fromarray 功能时候, 我们要保证数组中的值都是在0到255之间, np.asarray(np.clip(derained, 0, 255), dtype=”uint8”).
  • 此时主要用到的就是函数clip可以将一个数组中的数值全部局限在后面两个值之间.

除了PIL, 我们还可以使用matplotlib

  • 除了PIL, 我们也可以使用matplotlib来进行python的图像操作, 使用这个库进行图像操作时候,使用plt.imread()来加载图片,注意这个时候,整个图片是一个numpy的数组,无法进行图片的增强操作.
  • 使用matplotlib的一个好处是可以使用pylab来进行图片的保存,同时可以直接从numpy数组绘制整个图片.

图像处理相关问题

阅读数 244

没有更多推荐了,返回首页