计算OpenCV中像素值之间的距离长度

时间:2016-11-01 18:11:37

标签: c++ opencv

我需要创建两个图像的差异图像,并希望得到每个像素差异的大小/长度

我目前正在这样做:

cv::Mat diff = cv::abs(img1 - img2);
cv::Mat diffLen(diff.size(), CV_32FC1);
for(int x = 0; x < diff.size().width; ++x)
    for(int y = 0; y < diff.size().height; ++y)
    {
        float d = cv::norm(diff.at<Vec3f>(Point(x,y)));
        diffLen.at<float>(Point(x,y)) = d;
    }

有更方便的方法吗?

2 个答案:

答案 0 :(得分:1)

可能你可以使用ParallelLoopBody:

class ParallelNorm : public ParallelLoopBody
{
private:
    Mat &diff;
    Mat &diffLen;

public:
    ParallelNorm(Mat& pDiff,Mat &result) :
        diff(pDiff),
        diffLen(result)
        {}
    virtual void operator()(const Range& range) const
    {

        for (int x = range.start; x < range.end; ++x)
        {
            for (int y = 0; y < diffLen.rows; ++y)
            {
                float d = cv::norm(diff.at<Vec3f>(Point(x, y)));
                diffLen.at<float>(Point(x, y)) = d;
            }

        }
    }
};

而不是你的循环使用

ParallelNorm x(diff,diffLen);
parallel_for_(Range(0,diff.cols),x);

在循环中,如果交换x和y ...

,则可以使用指针

答案 1 :(得分:1)

我正在寻找类似的目的,这就是我现在得到的:

public class ImageAdapter extends BaseAdapter {
    private Context ctx;
    private int pos;
    private LayoutInflater inflater;
    private ImageView mImageView;
    ArrayList<Uri> mArrayUri;

    public ImageAdapter(Context ctx, ArrayList<Uri> mArrayUri) {

        this.ctx = ctx;
        this.mArrayUri = mArrayUri;
    }

    @Override
    public int getCount() {
        return mArrayUri.size();
    }

    @Override
    public Object getItem(int position) {
        return mArrayUri.get(position);
    }
    void addToList(Uri uriPath)
    {
        this.mArrayUri.add(uriPath);
        this.notifyDataSetChanged();
    }
    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
  
        View view = convertView;

        ViewHolder holder;
        Bitmap bitmap;
        if (view == null) {
            holder = new ViewHolder();
            LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.images_item, null);
            //view = ctx.getLayoutInflater().inflate(R.layout.images_item, null);
            holder.mImageView = (ImageView) view.findViewById(R.id.imageView_Gallery);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }

        if (Build.VERSION.SDK_INT >= 29) {
            ImageDecoder.Source source = ImageDecoder.createSource(ctx.getContentResolver(), mArrayUri.get(position));
            try {
                bitmap = ImageDecoder.decodeBitmap(source);
                mImageView.setImageBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            try {
                bitmap = MediaStore.Images.Media.getBitmap(ctx.getContentResolver(), mArrayUri.get(position));
                mImageView.setImageBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

            return view;
        }

        class ViewHolder {
            private ImageView  mImageView;
        }
    }

这不优雅。但似乎opencv不提供“像素级规范”操作。