Ask Your Question

Oliv's profile - activity

2016-02-08 03:48:18 -0600 received badge  Self-Learner (source)
2016-02-08 03:35:08 -0600 answered a question High `cv::solve` error if trained on single line

A plane can be defined by 3 points, that are not on the same line. This seems to be an edge case for the algorithm, that should actually fail with infinitely many solutions. Although extrapolations can be made for point on the same line, the error seems to be prohibitely large. For points not on the line, the extrapolations are insane.

A workaround seems to be to add a small value, so that the input data are not precisely on the same line. In the example in the question, adding 0.0001 to the first row produced this results:

X     Y     Z'
----  ----  -----
4     7     463.17
5     7     553.736
7     7     734.869
8     7     825.435

Adding this to the program might be easier, but it would more correct to avoid such cases or to use simple linear regression in this case.

2016-02-05 16:55:55 -0600 asked a question High `cv::solve` error if trained on single line

I use cv::solve to solve two dimensional linear regression. If the training data happen to be on single line (that is, y is equal for all training variables, then the extrapolation produces large error.

Say, the training data are:

X     Y     Z
----  ----  -----
4     7     458
5     7     554
7     7     735
8     7     826

The calculated coefficients are (notice the last two are very large numbers):

{92.8825, 3.74394e+007, -2.62076e+008}

If I use these to extrapolate the original values, large error is produced:

X     Y     Z'
----  ----  -----
4     7     427.53
5     7     520.412
7     7     706.177
8     7     799.06

All values are smaller by about 26-30. This seems to be an edge case. In my use case, if I have values all on single line (horizontal or vertical), I will predict the values only for that line, turning it effectively into one-dimensional linear regression. But the error is unacceptable.

Here is the code:

static void print(float a, float b, float c, int x, int y) {
    cout << "x=" << x << ", y=" << y << ", z=" << (a*x + b*y + c) << endl;
}

int main() {
    Mat matX(4, 3, CV_32F);
    Mat matZ(4, 1, CV_32F);

    int idx = 0;
    matX.at<float>(idx, 0) = 4;
    matX.at<float>(idx, 1) = 7;
    matX.at<float>(idx, 2) = 1;
    matZ.at<float>(idx++, 0) = 458;

    matX.at<float>(idx, 0) = 5;
    matX.at<float>(idx, 1) = 7;
    matX.at<float>(idx, 2) = 1;
    matZ.at<float>(idx++, 0) = 554;

    matX.at<float>(idx, 0) = 7;
    matX.at<float>(idx, 1) = 7;
    matX.at<float>(idx, 2) = 1;
    matZ.at<float>(idx++, 0) = 734;

    matX.at<float>(idx, 0) = 8;
    matX.at<float>(idx, 1) = 7;
    matX.at<float>(idx, 2) = 1;
    matZ.at<float>(idx++, 0) = 826;

    Mat res(3, 1, CV_32F);

    cv::solve(matX, matZ, res, DECOMP_QR);

    float a = res.at<float>(0);
    float b = res.at<float>(1);
    float c = res.at<float>(2);

    cout << "a=" << a << ", b=" << b << ", c=" << c << endl;
    print(a, b, c, 4, 7);
    print(a, b, c, 5, 7);
    print(a, b, c, 6, 7);
    print(a, b, c, 7, 7);
    print(a, b, c, 8, 7);
}
2015-11-04 05:55:53 -0600 received badge  Supporter (source)
2015-07-08 07:42:21 -0600 asked a question How to use lambda as a parameter to parallel_for_

Is it possible to pass the functor to parallel_for_ as a lambda?

cv::parallel_for_(cv::Range(0, X), [&] (const cv::Range & r) {
    for (int index = r.start; index != r.end; ++index) {
        // do work
    }
});

The above code fails to compile:

..\src\test.cpp: In function 'int main()':
..\src\test.cpp:29:3: error: invalid initialization of reference of type 'const cv::ParallelLoopBody&' from expression of type 'main()::<lambda(const cv::Range&)>'
C:\opencv\build\include/opencv2/core/core.hpp:4787:17: error: in passing argument 2 of 'void cv::parallel_for_(const cv::Range&, const cv::ParallelLoopBody&, double)'

I'd like to capture local variables.

2015-06-23 07:56:54 -0600 commented answer Android x86_64 support?
2015-06-22 00:39:36 -0600 received badge  Self-Learner (source)
2015-06-22 00:39:31 -0600 received badge  Editor (source)
2015-06-22 00:39:03 -0600 answered a question How to enable CV_DbgAssert on Android

I found the solution, I needed to move the line include $(CLEAR_VARS) before the LOCAL_CFLAGS line, here is modified Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_CPPFLAGS := -D_DEBUG
LOCAL_CFLAGS := -D_DEBUG

OPENCV_LIB_TYPE:=STATIC
include d:\OpenCV-2.4.11-android-sdk\sdk\native\jni\OpenCV.mk

LOCAL_MODULE    := recognizer
LOCAL_SRC_FILES := /* file list */
LOCAL_LDLIBS    += -llog
include $(BUILD_SHARED_LIBRARY)
2015-06-19 16:25:34 -0600 received badge  Student (source)
2015-06-19 15:56:57 -0600 asked a question How to enable CV_DbgAssert on Android

I have 5000 line algorithm and if fails with SIGSEGV on Android. I found out, that range checking is only done if _DEBUG is defined.

I my Android.mk I have LOCAL_CFLAGS := -D_DEBUG, but the debug assertions are still not executed. How to enable them? Here is my complete Android.mk file:

LOCAL_CPPFLAGS := -D_DEBUG
LOCAL_CFLAGS := -D_DEBUG

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
OPENCV_LIB_TYPE:=STATIC
include d:\OpenCV-2.4.11-android-sdk\sdk\native\jni\OpenCV.mk

LOCAL_MODULE    := recognizer
LOCAL_SRC_FILES := /* file list */
LOCAL_LDLIBS    += -llog
include $(BUILD_SHARED_LIBRARY)
2013-03-04 03:51:22 -0600 answered a question Get line values for cvHoughLines2

cvHoughLines2 returns the lines sorted by the accumulator value descendingly, thus taking first lines of the returned array solves the problem, even though I don't get the accumulator values.

Thanks to this message: http://tech.groups.yahoo.com/group/OpenCV/message/55201

2013-02-25 04:03:25 -0600 commented question Get line values for cvHoughLines2

I'm detecting a lattice-like shape consisting of 32 lines, but under different light conditions and the original object colours and contrast I get very high variations in the number of lines using constant threshold. During testing, 200 strongest lines do the work, but I can't use this function because the results are already postprocessed and information discarded. I want to know, if it is possible to get the accumulator matrix, or postprocess the matrix into lines in a different way. I'm interested in the CV_HOUGH_STANDARD version. (Editing question causes Internal server error...)

2013-02-25 03:59:34 -0600 commented answer Get line values for cvHoughLines2

I want the accumulator values. If I get 6000 lines, I'm not able to postprocess them, because lines cross the image all the way around. Iteratively adapting the threshold to get desired number of lines is just wasting CPU time.

2013-02-20 00:10:52 -0600 asked a question Get line values for cvHoughLines2

Is it possible to find line values for cvHoughLines2? By using only threshold, I get 150 to 6000 lines, depending on the input image. If I increase the threshold, I get reasonable number for the image for which I previously got 6000 lines, but in this case I get too few lines for the less contrasting image.

Is it possible to either:

  • get the line values?

  • get only specified number of strongest lines?