All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bytedeco.javacv.cvkernels Maven / Gradle / Ivy

/*
 * Copyright (C) 2009-2012 Samuel Audet
 *
 * Licensed either under the Apache License, Version 2.0, or (at your option)
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation (subject to the "Classpath" exception),
 * either version 2, or any later version (collectively, the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     http://www.gnu.org/licenses/
 *     http://www.gnu.org/software/classpath/license.html
 *
 * or as provided in the LICENSE.txt file that accompanied this code.
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.bytedeco.javacv;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import static org.bytedeco.javacpp.opencv_core.*;

/**
 *
 * @author Samuel Audet
 */
public class cvkernels extends org.bytedeco.javacpp.cvkernels {

    private static class ParallelData {
        KernelData data = null;
        CvRect roi = new CvRect();
    }
    private static ThreadLocal parallelData = new ThreadLocal() {
        @Override protected ParallelData[] initialValue() {
            ParallelData[] pd = new ParallelData[Parallel.getNumThreads()];
            for (int i = 0; i < pd.length; i++) {
                pd[i] = new ParallelData();
            }
            return pd;
        }
    };

    public static void multiWarpColorTransform(final KernelData data, final CvRect roi, final CvScalar fillColor) {
        final int size = (int)data.capacity();
        final ParallelData[] pd = parallelData.get();

        // Copy all data to completely independent data sets
        for (int i = 0; i < pd.length; i++) {
            if (pd[i].data == null || pd[i].data.capacity() < size) {
                pd[i].data = new KernelData(size);
                for (int j = 0; j < size; j++) {
                    KernelData d = pd[i].data.position(j);
                    data.position(j);
                    if (data.dstDstDot() != null) {
                        d.dstDstDot(ByteBuffer.allocateDirect(data.dstDstDot().capacity()*8).
                                order(ByteOrder.nativeOrder()).asDoubleBuffer());
                    }
                }
            }
            for (int j = 0; j < size; j++) {
                KernelData d = pd[i].data.position(j);
                d.put(data.position(j));
                d.dstDstDot(d.dstDstDot()); // reset dstDstDot pointer
            }
        }

        // Transform in parallel on multiple threads
        final IplImage img = data.position(0).srcImg();
        final int depth = img.depth();
        final int x, y, w, h;
        if (roi != null) {
            x = roi.x();     y = roi.y();
            w = roi.width(); h = roi.height();
        } else {
            x = 0;           y = 0;
            w = img.width(); h = img.height();
        }
        Parallel.loop(y, y+h, pd.length, new Parallel.Looper() {
        public void loop(int from, int to, int looperID) {
            CvRect r = pd[looperID].roi.x(x).y(from).width(w).height(to-from);
            if (depth == IPL_DEPTH_32F) {
                multiWarpColorTransform32F(pd[looperID].data.position(0), size, r, fillColor);
            } else if (depth == IPL_DEPTH_8U) {
                multiWarpColorTransform8U(pd[looperID].data.position(0), size, r, fillColor);
            } else {
                assert false;
            }
        }});

        // Reduce data as required
        for (int i = 0; i < size; i++) {
            int dstCount = 0;
            int dstCountZero = 0;
            int dstCountOutlier = 0;
            double srcDstDot = 0;
            double[] dstDstDot = null;
            if (data.dstDstDot() != null) {
                dstDstDot = new double[data.dstDstDot().capacity()];
            }
            for (int j = 0; j < pd.length; j++) {
                KernelData d = pd[j].data.position(i);
                dstCount        += d.dstCount();
                dstCountZero    += d.dstCountZero();
                dstCountOutlier += d.dstCountOutlier();
                srcDstDot       += d.srcDstDot();
                if (dstDstDot != null && d.dstDstDot() != null) {
                    for (int k = 0; k < dstDstDot.length; k++) {
                        dstDstDot[k] += d.dstDstDot().get(k);
                    }
                }
            }
            data.position(i);
            data.dstCount(dstCount);
            data.dstCountZero(dstCountZero);
            data.dstCountOutlier(dstCountOutlier);
            data.srcDstDot(srcDstDot);
            if (dstDstDot != null && data.dstDstDot() != null) {
                data.dstDstDot().position(0);
                data.dstDstDot().put(dstDstDot);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy