# change source and recompile

Hi I'd like to change the opencv source a bit and recompile (I'd like access to the hough transform 'accumulator' image, which I see in the modules/imgproc/hough.cpp source but isn't exposed). So what I did was make a copy of the function cv::HoughLines in hough.cpp , called it cv::HoughLinesWithAccumulator and made the corresponding definition in the imgproc.hpp file, then did a cmake which seemed to go ok (although there is some sort of download step, which I hope isn't somehow avoiding my changed code).
Hoping for a miracle (actually hoping for automatic wrapper-creation) I tried calling cv2.HoughLinesWithAccumulator instead of the working cv2.HoughLines call from my python code (which is where I've been using opencv for abt 1 yr) and as expected no such function exists in the opencv module. So I'm downloading a C++ IDE and will try to call my new func from there; if that works, then I'll try to figure out how the python wrappers get made, and add my new function there. Does this sound reasonable, are there some pitfalls and/or easier ways?

edit retag close merge delete

1

take a look here

did you prefix your new method declaration with a proper CV_EXPORTS_W ?

and yes, you will have to rebuild the opencv libs (and re-install cv2.pyd) to make it happen, though i doubt, that you need a c++ ide for this.

( 2015-02-22 05:16:24 -0500 )edit

Thanks for your help first off, so far no dice: I had a declaration in include/opencv2/imgproc.hpp, monkeying the declaration that was already there for houghlines, for my version which i called houghlineswithaccumulator (in meantime keeping same arguments)

CV_EXPORTS_W void HoughLinesWithAccumulator( InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double srn = 0, double stn = 0,
double min_theta = 0, double max_theta = CV_PI


I read the link, thx I'm not sure how to resintall cv2.pyd , I tried find -name cv2.pyd and locate cv2.pyd but didn't find it. The C++ ide was just to check whether i can first of all call my new function from C++, next step pyt

( 2015-02-24 05:00:41 -0500 )edit

the usual steps are:

• cmake
• make
• make install (this will copy your new cv2.pyd to the site-packages folder)

then start python, import cv2, and do a help(cv2.HoughLinesWithAccumulator)to see, if it got in.

( 2015-02-24 05:06:12 -0500 )edit
1

whoops it looks like i shoudlve realized from your answer that i needed to copy the newly generated cv2.so to /usr/lib/python2.7/dist-package . Having done so I can now call my newly minted function, great! Now I will try changing arguments etc to actually get the output i need.

Just saw your above answer, yes that wouldve taken care of it. Thanks again for help, it looks like i am in right direction for the time being

( 2015-02-24 05:34:30 -0500 )edit

a few birthing pains. I tried adding an output array to my function

void cv::HoughLinesWithAccumulator( InputArray _image, OutputArray _lines, OutputArray _accumulator, double rho, double theta, int threshold, double srn, double stn, double min_theta, double max_theta )


along with the corresponding declaration in the .hpp header. This suffices to break my opencv install - i get the following ImportError: /usr/lib/python2.7/dist-packages/cv2.so: undefined symbol: _ZN2cv25HoughLinesWithAccumulatorERKNS_11_InputArrayERKNS_12_OutputArrayEddidddd

I don't think its related to allocating an array for the accumulator , i tried a few things such as Mat accumulator; accumulator.copyTo(_accumulator) or _accumulator = _image but no dice

( 2015-02-25 07:45:59 -0500 )edit
1

make sure, your declaration and definition match exactly. seems, you compiled something different, than you showed to the python wrapper

"I don't think its related to allocating an array for the accumulator" - don't think so , too. if you do something wrong there, it will either lead to an empty Mat returned, or a runtime crash, not a linker error as above.

( 2015-02-25 08:04:12 -0500 )edit

I can't seem to figure it - I added exactly one argument to the .cpp function and same to the .hpp, in the same place, with same type - .hpp entry below , in /opencv_src/modules/imgproc/include/opencv2/imgproc.hpp (and not in the .../include/opencv2/imgproc/imgproc.hpp which it looks like is not the right one):

CV_EXPORTS_W void HoughLinesWithAccumulator( InputArray image, OutputArray lines, OutputArray accumulator,
double rho, double theta, int threshold,
double srn = 0, double stn = 0,
double min_theta = 0, double max_theta = CV_PI );

( 2015-02-25 08:36:36 -0500 )edit
1

ok, seems as tho the cv2.so wasn't getting regenerated after the cmake, make -j2 , and make install. So I wiped out the build directory and am trying again .

( 2015-02-25 11:45:11 -0500 )edit

Now I get a working cv2.so (which i have to copy by hand into /usr/lib/python2.7/dist-packages , make install doesn't seem to do this). But I don't seem to have access to the extra output argument : when i try

lines = cv2.HoughLinesWithAccumulator(edges,1,np.pi/180,200)
lines, arr = cv2.HoughLinesWithAccumulator(edges,1,np.pi/180,200)


the first line is ok while the second gives a 'too many values to unpack' so i guess my OutputArray is not getting picked up by the gen2 and/or hdr_parser scripts. I'll see if I can find output of those guys somewhere.

( 2015-02-25 13:07:55 -0500 )edit
1

another small step forward (i think) - now i get an error 139 in python indicating bad memory access - so I'll try something besides the test I was attempting namely

_image.copyTo(_accumulator);


which was an attempt to get the input image back as output image. I'll try

Mat accumulator;
_accumulator = accumulator;

( 2015-02-26 04:34:52 -0500 )edit

the target for copyTo must not be empty.

if _accumulator is you OutputArray, try _accumulator.assign(someMat)

( 2015-02-26 04:39:15 -0500 )edit

so is the doc here wrong ( "m - Destination matrix. If it does not have a proper size or type before the operation, it is reallocated") or is it the case that this is only true for calls to copyTo from outside opencv, or what? in any case in meantime i tried

   _accumulator.create(src.size(), src.type());
Mat accumulator = _accumulator.getMat();

for( int i = 0; i < src.rows; i++ )
for( int j = 0; j < src.cols; j++ )
{
accumulator.at<Point2f>(i, j) = src.at<Point2f>(i,j);
}


This gave trouble (an assertion fail in some malloc) . I'm looking for an opencv coding guide so maybe that'll help

( 2015-02-26 11:07:09 -0500 )edit

I have yet to crack this nut

Mat image = _image.getMat();
Mat accumulator = _image.getMat();
HoughLinesStandardWithAccumulator(image, (float)rho, (float)theta, threshold, lines, accumulator, INT_MAX, min_theta, max_theta );
_accumulator.assign(image);


gets me an error 139 on exiting my function HoughLinesWithAccumulator

( 2015-02-28 12:47:08 -0500 )edit

I'm not sure what was wrong before but this one has started to work:

Mat image = _image.getMat();
std::vector<Vec2f> lines;
Mat accumulator = _image.getMat();
if( srn == 0 && stn == 0 )
HoughLinesStandardWithAccumulator(image, (float)rho, (float)theta, threshold, lines, accumulator, INT_MAX, min_theta, max_theta );
Mat(lines).copyTo(_lines);
image.copyTo(_accumulator);

( 2015-02-28 17:22:21 -0500 )edit

ok so now that I have my new arguments and don't crash anything I'd like to finally get the data I am after which is located in an 'autobuffer'

AutoBuffer<int> _accum((numangle+2) * (numrho+2));


and I'd like to get that data into my inputarray ; I don't seem to be able to access Mat values using m.[row][column] , how would I do this efficiently? Specifically I have a Mat called accumulator which I made as follows

Mat accumulator = _acc.getMat();  //JR
accumulator.create(numangle+2,numrho+2,sizeof(accum[0]));  //JR
for(int r = 0; r < numrho; r++ )
for(int n = 0; n < numangle; n++ )
{
int base = (n+1) * (numrho+2) + r+1;
accumulator[r][n] = accum[base];  //JR
}


but that last line is not going to hack it I blv .

( 2015-03-01 05:47:09 -0500 )edit

To convert the extant variable accum (which is a (numrho+2)*(numangle+2) long vector of ints) into a 2-dimensional Mat of uchars called accumulator, and put that Mat into an OutputArray called _acc, I did the following -

int s = sizeof(accum[0]);
_acc.create(numangle+2,numrho+2,s);  //JR
Mat accumulator = _acc.getMat();  //JR
for(int r = 0; r < numrho; r++ )
for(int n = 0; n < numangle; n++ )    {
int base = (n+1) * (numrho+2) + r+1;
accumulator.data[base*s+3] = accum[base]%256;  //JR
accumulator.data[base*s+2] = (accum[base]>>8)%256;  //JR
accumulator.data[base*s+1]  = (accum[base]>>16)%256;  //JR
accumulator.data[base*s+0] = (accum[base]>>24)%256;  //JR
}


reasonable?

( 2015-03-01 11:38:50 -0500 )edit

Hi Jeremy, I think it has been a long time since you worked on this project. I am also looking for a version of HoughLines returning the accumulator. I've already managed to do it in c++, but I need to compile it to make a python version of this new function. Did you managed to use it on python ?

( 2020-07-28 08:03:55 -0500 )edit