Ask Your Question

Revision history [back]

confused on Mat put

I'm a newer on java opencv, now i have a few confusion on Mat put functions.

The confusion is: the behavior of Mat.put(int ,int, double ...) and Mat.put(int, int, float[]) are different ( the 2 functions are in org.opencv.core.Mat.java line 2493 and line 2504). So i tried to look why by viewing source code and i found the native code are located in opencv-2.4.7/modules/java/generator/src/cpp/Mat.cpp

nPutF for put(int, int, float[])'s code:

1931 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF 1932 (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jfloatArray vals); 1933 1934 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF 1935 (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jfloatArray vals) 1936 { 1937 static const char method_name[] = "Mat::nPutF()"; 1938 try { 1939 LOGD("%s", method_name); 1940 cv::Mat* me = (cv::Mat) self; 1941 if(! self) return 0; // no native object behind 1942 if(me->depth() != CV_32F) return 0; // incompatible type 1943 if(me->rows<=row || me->cols<=col) return 0; // indexes out of range 1944 1945 char values = (char*)env->GetPrimitiveArrayCritical(vals, 0); 1946 int res = mat_put<float>(me, row, col, count, values); 1947 env->ReleasePrimitiveArrayCritical(vals, values, 0); 1948 return res; 1949 } catch(const std::exception &e) { 1950 throwJavaException(env, &e, method_name); 1951 } catch (...) { 1952 throwJavaException(env, 0, method_name); 1953 } 1954 1955 return 0; 1956 }

----------and here is mat_put

1817 template<typename t=""> static int mat_put(cv::Mat* m, int row, int col, int count, char* buff) 1818 { 1819 if(! m) return 0; 1820 if(! buff) return 0; 1821 1822 count *= sizeof(T); 1823 int rest = ((m->rows - row) * m->cols - col) * (int)m->elemSize(); 1824 if(count>rest) count = rest; 1825 int res = count; 1826 1827 if( m->isContinuous() ) 1828 { 1829 memcpy(m->ptr(row, col), buff, count); 1830 } else { 1831 // row by row 1832 int num = (m->cols - col) * (int)m->elemSize(); // 1st partial row 1833 if(count<num) num="count;" 1834="" uchar*="" data="m-">ptr(row++, col); 1835 while(count>0){ 1836 memcpy(data, buff, num); 1837 count -= num; 1838 buff += num; 1839 num = m->cols * (int)m->elemSize(); 1840 if(count<num) num="count;" 1841="" data="m-">ptr(row++, 0); 1842 } 1843 } 1844 return res; 1845 }

but nPutD for put(int, int, double ...):

1757 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD 1758 (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals); 1759 1760 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD 1761 (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals) 1762 { 1763 static const char method_name[] = "Mat::nPutD()"; 1764 try { 1765 LOGD("%s", method_name); 1766 cv::Mat* me = (cv::Mat) self; 1767 if(!me || !me->data) return 0; // no native object behind 1768 if(me->rows<=row || me->cols<=col) return 0; // indexes out of range 1769 1770 int rest = ((me->rows - row) * me->cols - col) * me->channels(); 1771 if(count>rest) count = rest; 1772 int res = count; 1773 double values = (double)env->GetPrimitiveArrayCritical(vals, 0); 1774 double src = values; 1775 int r, c; 1776 for(c=col; c<me->cols && count>0; c++) 1777 { 1778 switch(me->depth()) { 1779 case CV_8U: PUT_ITEM(uchar, row, c); break; 1780 case CV_8S: PUT_ITEM(schar, row, c); break; 1781 case CV_16U: PUT_ITEM(ushort, row, c); break; 1782 case CV_16S: PUT_ITEM(short, row, c); break; 1783 case CV_32S: PUT_ITEM(int, row, c); break; 1784 case CV_32F: PUT_ITEM(float, row, c); break; 1785 case CV_64F: PUT_ITEM(double, row, c); break; 1786 } 1787 } 1788 1789 for(r=row+1; r<me->rows && count>0; r++) 1790 for(c=0; c<me->cols && count>0; c++) 1791 { 1792 switch(me->depth()) { 1793 case CV_8U: PUT_ITEM(uchar, r, c); break; 1794 case CV_8S: PUT_ITEM(schar, r, c); break; 1795 case CV_16U: PUT_ITEM(ushort, r, c); break; 1796 case CV_16S: PUT_ITEM(short, r, c); break; 1797 case CV_32S: PUT_ITEM(int, r, c); break; 1798 case CV_32F: PUT_ITEM(float, r, c); break; 1799 case CV_64F: PUT_ITEM(double, r, c); break; 1800 } 1801 } 1802 1803 env->ReleasePrimitiveArrayCritical(vals, values, 0); 1804 return res; 1805 } catch(const std::exception &e) { 1806 throwJavaException(env, &e, method_name); 1807 } catch (...) { 1808 throwJavaException(env, 0, method_name); 1809 } 1810 1811 return 0; 1812 }


it seems nPutD will modify all elements after (row, col), because count will never update. but nPutF will update count when modified element (row, col), so it just modified several elements with given data.

Am i right?

so why the 2 functions (the source is same as version 3.2.0) behaivor differently?

click to hide/show revision 2
No.2 Revision

updated 2017-08-10 00:29:17 -0600

berak gravatar image

confused on Mat put

I'm a newer on java opencv, now i have a few confusion on Mat put functions.

The confusion is: the behavior of Mat.put(int ,int, double ...) and Mat.put(int, int, float[]) are different ( the 2 functions are in org.opencv.core.Mat.java line 2493 and line 2504). So i tried to look why by viewing source code and i found the native code are located in opencv-2.4.7/modules/java/generator/src/cpp/Mat.cpp

nPutF for put(int, int, float[])'s code:

 1931 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
1932 (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jfloatArray vals);
1933
1934 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
1935 (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jfloatArray vals)
1936 {
1937 static const char method_name[] = "Mat::nPutF()";
1938 try {
1939 LOGD("%s", method_name);
1940 cv::Mat* me = (cv::Mat) (cv::Mat*) self;
1941 if(! self) return 0; // no native object behind
1942 if(me->depth() != CV_32F) return 0; // incompatible type
1943 if(me->rows<=row || me->cols<=col) return 0; // indexes out of range
1944
1945 char char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0);
1946 int res = mat_put<float>(me, row, col, count, values);
1947 env->ReleasePrimitiveArrayCritical(vals, values, 0);
1948 return res;
1949 } catch(const std::exception &e) {
1950 throwJavaException(env, &e, method_name);
1951 } catch (...) {
1952 throwJavaException(env, 0, method_name);
1953 }
1954
1955 return 0;
1956 }

}

----------and here is mat_put

 1817 template<typename t=""> T> static int mat_put(cv::Mat* m, int row, int col, int count, char* buff)
1818 {
1819 if(! m) return 0;
1820 if(! buff) return 0;
1821
1822 count *= sizeof(T);
1823 int rest = ((m->rows - row) * m->cols - col) * (int)m->elemSize();
1824 if(count>rest) count = rest;
1825 int res = count;
1826
1827 if( m->isContinuous() )
1828 {
1829 memcpy(m->ptr(row, col), buff, count);
1830 } else {
1831 // row by row
1832 int num = (m->cols - col) * (int)m->elemSize(); // 1st partial row
1833 if(count<num) num="count;" 1834="" uchar*="" data="m-">ptr(row++, num = count;
1834 uchar* data = m->ptr(row++, col);
1835 while(count>0){
1836 memcpy(data, buff, num);
1837 count **count -= num; num;**
 1838 buff += num;
1839 num = m->cols * (int)m->elemSize();
1840 if(count<num) num="count;" 1841="" data="m-">ptr(row++, num = count;
1841 data = m->ptr(row++, 0);
1842 }
1843 }
1844 return res;
1845 }

}

but nPutD for put(int, int, double ...):

 1757 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD
1758 (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals);
1759
1760 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD
1761 (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals)
1762 {
1763 static const char method_name[] = "Mat::nPutD()";
1764 try {
1765 LOGD("%s", method_name);
1766 cv::Mat* me = (cv::Mat) (cv::Mat*) self;
1767 if(!me || !me->data) return 0; // no native object behind
1768 if(me->rows<=row || me->cols<=col) return 0; // indexes out of range
1769
1770 int rest = ((me->rows - row) * me->cols - col) * me->channels();
1771 if(count>rest) count = rest;
1772 int res = count;
1773 double double* values = (double)env->GetPrimitiveArrayCritical(vals, (double*)env->GetPrimitiveArrayCritical(vals, 0);
1774 double double* src = values;
1775 int r, c;
1776 for(c=col; for**(c=col; c<me->cols && count>0; c++) c++)**
 1777 {
1778 switch(me->depth()) {
1779 case CV_8U: PUT_ITEM(uchar, row, c); break;
1780 case CV_8S: PUT_ITEM(schar, row, c); break;
1781 case CV_16U: PUT_ITEM(ushort, row, c); break;
1782 case CV_16S: PUT_ITEM(short, row, c); break;
1783 case CV_32S: PUT_ITEM(int, row, c); break;
1784 case CV_32F: PUT_ITEM(float, row, c); break;
1785 case CV_64F: PUT_ITEM(double, row, c); break;
1786 }
1787 }
1788
1789 for(r=row+1; r<me->rows && count>0; r++)
1790 for(c=0; c<me->cols && count>0; c++)
1791 {
1792 switch(me->depth()) {
1793 case CV_8U: PUT_ITEM(uchar, r, c); break;
1794 case CV_8S: PUT_ITEM(schar, r, c); break;
1795 case CV_16U: PUT_ITEM(ushort, r, c); break;
1796 case CV_16S: PUT_ITEM(short, r, c); break;
1797 case CV_32S: PUT_ITEM(int, r, c); break;
1798 case CV_32F: PUT_ITEM(float, r, c); break;
1799 case CV_64F: PUT_ITEM(double, r, c); break;
1800 }
1801 }
1802
1803 env->ReleasePrimitiveArrayCritical(vals, values, 0);
1804 return res;
1805 } catch(const std::exception &e) {
1806 throwJavaException(env, &e, method_name);
1807 } catch (...) {
1808 throwJavaException(env, 0, method_name);
1809 }
1810
1811 return 0;
1812 }

}

it seems nPutD will modify all elements after (row, col), because count will never update. but nPutF will update count when modified element (row, col), so it just modified several elements with given data.

Am i right?

so why the 2 functions (the source is same as version 3.2.0) behaivor differently?