在我正在开发的Android应用程序中(使用OpenCV4Android),我有一个包含整数值的矩阵(Mat对象)和另一个作为查找表的行矩阵。我需要创建第一个矩阵的大小的新矩阵,其中每个值都替换为对应的查找表值(即newMat(x,y) = lookupTable(oldMat(x,y)))。对于初学者来说,我知道有一个Core.LUT()函数,但是它在这里无济于事,因为我不一定要使用CvType.CV_8U类型的Mat s,并且查找表可能大于256个值。我将主要使用单通道浮点数(CvType.CV_32FC1)。我想出了以下解决方案:// init matricesMat oldMat = initOldMat(); // contains values from 0 to k-1Mat newMat = new Mat(oldMat.size(), oldMat.type());Mat LUT = initLUT(); // a row matrix with k columns// copying data from matrices to arraysfloat[] oldMatArr = new float[(int)oldMat.total()];oldMat.put(0,0,oldMarArr);float[] lutArr= new float[(int)LUT.total()];oldMat.put(0,0,lutArr);// initialize array for the new matrixfloat[] newMatArr = new float[oldMatArr.length];// applying the LUT - see function belowapplyLUTonData(oldMatArr, lutArr, newMatArr);// copy the data to the new matrixnewMat.put(0, 0, newMatArr);private void applyLUTonData(float[] inputData, float[] lut, float[] outputData) { if (inputData.length != outputData.length) { Log.e(TAG, "applyLUTonData: inputData.length != outputData.length", new IllegalArgumentException("inputData.length != outputData.length")); } if (Floats.min(inputData) < 0 || Floats.max(inputData) > lut.length) { Log.e(TAG, "applyLUTonData: Invalid values in inputData", new IllegalArgumentException("Invalid values in inputData")); } for (int i = 0; i < inputData.length; i++) { if (inputData[i] != Math.round(inputData[i])) { // not an int Log.e(TAG, "applyLUTonData: inputData contains non-integers", new IllegalArgumentException("inputData contains non-integers")); } outputData[i] = lut[(int) inputData[i]]; } }注意:我知道inputData包含浮点数有点奇怪。当然,我可以将其转换为某些整数类型的矩阵/数组,但是我仍然无法使用Core.LUT,因为我的LUT可能包含非整数值。它可以正常工作,很棒的,但是效率很低-此函数在嵌套的for循环中调用,最多3*k次(k是LUT的大小),并且需要很多时间。因此,我正在寻找一种有效的方法来实现相同的功能。它可以使用Java或OpenCV解决方案(包括诸如Guave之类的库)-取其有效。 最佳答案 我最终找到了一个解决方案-我没有将Mat对象转换为数组,而是将它们保留为Mat,然后将它们传递给函数。想法是将其“ slice ”为LUT中的值数量,一次处理每个值。例如-对于包含32个不同值的LUT,我将遍历输入数据(包含从0到31的整数),首先替换所有0,然后替换1,依此类推...这是我的代码:private static void applyLUTonData(Mat inputData, float[] LUT, Mat outputData, int nBins) { if (inputData.rows() != outputData.rows() || inputData.cols() != outputData.cols()) { Log.e(TAG, "applyLUTonData: inputData.size() != outputData.size()", new IllegalArgumentException("inputData.size() != outputData.size()")); return; } if (LUT.length != nBins) { Log.e(TAG, "applyLUTonData: Invalid length for LUT - " + nBins, new IllegalArgumentException("Invalid length for LUT - " + nBins)); return; } Core.MinMaxLocResult res = Core.minMaxLoc(inputData); if (res.minVal < 0 || res.maxVal >= nBins) { Log.e(TAG, "applyLUTonData: Invalid inputData values", new IllegalArgumentException("Invalid inputData values")); return; } // here's the magic Mat cmpMat = new Mat(); for (int i = 0; i < nBins; i++) { Core.compare(inputData, new Scalar(i), cmpMat, Core.CMP_EQ); outputData.setTo(new Scalar(LUT[i]), cmpMat); } cmpMat.release(); }复杂度而言,对于n像素图像,我的旧版本采用O(n)。具有大小为k的LUT的该版本采用O(k),这对于k
10-08 00:40