I want to make a sparse matrix in OpenCV.
How can I do the basic operation for this matrix like:
Putting or accessing data from matrix elements.
Cheers
Using the C++ interface might be more appropriate. Notice that the example code in the documentation [1] lacks the modulo operation und thus fails.
const int dims = 2;
int size[] = {3, 20}; // rows and columns if in two dimensions
SparseMat sparse_mat(dims, size, CV_32F);
for(int i = 0; i < 1000; i++) {
// create a random index in dims dimensions
int idx[dims];
for(int k = 0; k < dims; k++)
idx[k] = rand() % size[k];
sparse_mat.ref<float>(idx) += 1.f;
}
cout << "bottom right element # (2,19) = " << sparse_mat.ref<float>(2,19) << "\n";
Mat dense;
sparse_mat.convertTo(dense, CV_32F);
cout << dense;
Gives the following output
bottom right element # (2,19) = 19
[9, 23, 13, 26, 18, 13, 18, 15, 13, 17, 13, 18, 19, 6, 20, 20, 12, 15, 15, 15;
17, 17, 14, 16, 12, 14, 17, 15, 15, 18, 24, 18, 13, 22, 18, 11, 18, 22, 17, 15;
19, 16, 14, 10, 18, 19, 10, 17, 18, 15, 24, 22, 18, 18, 18, 23, 21, 16, 14, 19]
[1] The OpenCV Reference Manual. Version 2.4.3. 2012, p. 46.
Sets and Sparse Matrices, page 23:
Sparse matrix in OpenCV uses CvSet for storing elements.
CvSparseMat* get_color_map( const IplImage* img )
{
int dims[] = { 256, 256, 256 };
CvSparseMat* cmap = cvCreateSparseMat(3, dims, CV_32SC1);
for( int i = 0; i < img->height; i++ ) for( int j = 0; j < img->width; j++ )
{
uchar* ptr=&CV_IMAGE_ELEM(img,uchar,i,j*3);
int idx[] = {ptr[0],ptr[1],ptr[2]};
((int*)cvPtrND(cmap,idx))[0]++;
}
// print the map
CvSparseMatIterator it;
for(CvSparseNode *node = cvInitSparseMatIterator( mat, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
int* idx = CV_NODE_IDX(cmap,node);
int count=*(int*)CV_NODE_VAL(cmap,idx);
printf( ā(b=%d,g=%d,r=%d): %d\nā, idx[0], idx[1], idx[2], count );
}
return cmap;
}
Related
I have implemented 0-1 knapsack. "DP" is the 1D table that holds maximum profits. "capacity" is the maximum capacity, "n" is the number of elements. At the end it holds the last row of 2D classic approach in "DP". But i can't figure out how to get which elements are used with just looking at the 1D array.
DP = (int*)calloc(capacity + 1, sizeof(int));
used = (int*)calloc(n, sizeof(int));
for (i = 0; i < n; i++) {
for (j = capacity; j > 0; j--) {
if (weight[i] <= j && DP[j] < DP[j - weight[i]] + profit[i]) {
DP[j] = DP[j - weight[i]] + profit[i];
used[i] = 1;
}
}
}
// for example
// int profit[] = { 7, 16, 13, 8, 1, 11, 14, 11, 12, 7, 6, 10, 1, 1, 11, 12}
// int weight[] = { 6, 2, 7, 2, 1, 2, 5, 4, 12, 16, 1, 4, 10, 12, 12, 2}
// results DP = {0, 6, 16, 22, 28, 34, 39, 45, 47}
// total profit of used elements: 72 <- it should be 47
// total weight of used elements: 20 <- it should be lesser than 8(the capacity)
I have code to perform a permutation on a block of data (64 bit) and the code works but I don't understand how the addbit function works. This is the function that performs the permutation on a to and from bit position.
I understand that because if a bit gets over-written in the destination data block then if that previous bit needs to be permuted then it will be lost and that is why there is a source and destination data block.
But I dont understand the logic in addbit.
Why is FIRSTBIT used?
The code works, but I would like to understand why.
#include <stdint.h>
#include <stdio.h>
// FIRSTBIT is first bit in 64 bit data?
#define FIRSTBIT 0x8000000000000000 // 1000000000...
// eg move bit 64 in input data to bit position 1
// then move bit 63 in input data to bit position 2 etc
const int TestPermutation[64] = {
64, 63, 62, 61, 60, 59, 58, 57,
56, 55, 54, 53, 52, 51, 50, 49,
48, 47, 46, 45, 44, 43, 42, 41,
40, 39, 38, 37, 36, 35, 34, 33,
32, 31, 30, 29, 28, 27, 26, 25,
24, 23, 22, 21, 20, 19, 18, 17,
16, 15, 14, 13, 12, 11, 10, 9,
8, 7, 6, 5, 4, 3, 2, 1
};
// move data bit from 'from' at position_from to position_to in block
// How does this work?
void addbit(uint64_t *block, uint64_t from, int position_from, int position_to)
{
if (((from << (position_from)) & FIRSTBIT) != 0)
*block += (FIRSTBIT >> position_to);
}
// perform permutation based on TestPermutation array
void permute(uint64_t* data) {
uint64_t data_temp = 0;
for (int ii = 0; ii < 64; ii++)
{
addbit(&data_temp, *data, TestPermutation[ii] - 1, ii);
}
*data = data_temp;
}
void print_binary(uint64_t number) {
for (int i = sizeof(uint64_t) * 8 - 1; i >= 0; --i) {
printf("%c", ((number >> i) & 1) ? '1' : '0');
}
printf("\n");
}
int main() {
uint64_t data = 0xF0F0F0F0F0F0F0F0; // test block
print_binary(data); // 1111000011110000111100001111000011110000111100001111000011110000
permute(&data);
print_binary(data); // 0000111100001111000011110000111100001111000011110000111100001111
}
From list of collatz sequence that are like 34,17,52,26,13...4,2,1.I want to print 40 characters for each line like "50, 25, 76, 38, 19, 58, 29, 88, 44, 22," will be first line of 40 characters and then next line and should stop when last number are 4, 2, 1
I am unable to stop the program when 4, 2, 1 sequence is encountered.
I have first created the required sequence of numbers. Post that tried to print numbers by for loop with while condition of 1.
int length;
int *ptr;
int i = 50, j = 0;
for (i; i >= 2; )
{
if (i % 2 == 0)
{
i = i / 2;
}
else if (i % 2 != 0)
{
i = (3 * i) + 1;
}
ptr[j] = i;
printf("Total Value: %d, \n", ptr[j]);
j++;
}
for (i = 0; i < 50; )
{
j = 10 + i;
while (i < j)
{
printf("%d, ", ptr[i]);
i++;
if (ptr[i] == 1)
{
break;
}
}
printf("\n");
}
Expected result:
50, 25, 76, 38, 19, 58, 29, 88, 44, 22,
11, 34, 17, 52, 26, 13, 40, 20, 10, 5,
16, 8, 4, 2, 1,
For starters, your code causes a segmentation fault on my machine. You declared ptr as a pointer to an integer int *ptr;, but you are treating it as an array and storing values into it ptr[j] = i;. If you want to put data into an array, then you will either need to malloc a buffer or declare ptr as an array on the stack, i.e., int ptr[SIZE].
A pointer is not a means of storage itself. If you want to have an array for storage, then you need to explicitly allocate an array either on the stack or on the heap.
This is my code initializing the array:
#include <stdio.h>
int main (void) {
int x, n;
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int *array = {2, 4, 6, 9, 11, 13, 15, 17, 19, 21, 25, 29, 30, 34, 35, 38};
n = sizeof(array) / sizeof(int);
for (x=0; x<n; x++) {
printf("%i: %i - ", x, array[x]);
}
printf("\nArray's length: %i", n);
return 0;
}
I'm not understanding why this simple code shows this message:
Runtime error
Thanks in advance.
Change this:int *array = to this: int array[] =. Ideone link: https://ideone.com/ULH7i6 . See this too: How to initialize all members of an array to the same value?
What did you have in mind when you declared the following line?
int *array = {2, 4, 6, 9, 11, 13, 15, 17, 19, 21, 25, 29, 30, 34, 35, 38};
What comes to mind when I see something like this you're trying to work with an array using pointer arithmetic, which makes for a lot of fun interview questions (and just cool in general :P ). On the other hand you might just be used to being able to create arrays using array literals.
Below is something that talks about the different types of arrays you might be trying to work with. I know you picked an answer but this might be useful to you if you were trying to accomplish something else.
C pointer to array/array of pointers disambiguation
Your array declaration is not correct.... just edit your declaration to
int *array[] = {2, 4, 6, 9, 11, 13, 15, 17, 19, 21, 25, 29, 30, 34, 35, 38};
here the correction code!
#include <stdio.h>
int main (void) {
int x, n;
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int *array[] = {2, 4, 6, 9, 11, 13, 15, 17, 19, 21, 25, 29, 30, 34, 35, 38};
n =sizeof(array) / sizeof(int);
for (x=0; x<n; x++) {
printf("%i: %i - ",x,array[x]);
}
printf("\nArray's length: %i", n);
return 0;
}
I have 2D arrays in header files, for which I declared the sizes of both:
int numPaths = 2;
int pathLength = 11;
double x[numPaths][pathLength] = {{62, 114, 0, 73, 55, 21, -28, -93, 0, 0, 0},{-90, 208, 0, 4, 7, 10, 12, 13, 11, -198, -147}};
double y[numPaths][pathLength] = {{55, 88, 0, -42, 12, 45, 54, 40, 0, 0, 0},{269, -117, 0, -10, -14, -17, -20, -24, -69, -82, 20}};
I get this error: Array bound not an integer constant.
My 2D arrays are not dynamically changes, and I've declared the sizes of these arrays (numPaths and pathLength). I'm not sure what the problem is?
numPaths and pathLength aren't constants, just like the error message says. You need:
#define numPaths 2
#define pathLength 11
Some compilers will let you get away with:
const int numPaths = 2;
const int pathLength = 11;
As an extension.