My objective is to find the pattern in the image captured from camera for this I found the cv::matchShapes method of opencv to implement it.
When I have implemented this method it is making the app crash on matchShapes method.Might be I have done something wrong:-
I exactly do not know how to use this method in order to find the match shape in my query image.This is what I tried.
Here is my code:-
- (void)tryingMatchShapes:(cv::Mat)_image _image1:(cv::Mat)_image1
{
std::vector<std::vector<cv::Point> > squares;
cv::Mat pyr, timg, gray0(_image.size(), CV_8U), gray;
int thresh = 50, N = 11;
cv::pyrDown(_image, pyr, cv::Size(_image.cols/2, _image.rows/2));
cv::pyrUp(pyr, timg, _image.size());
std::vector<std::vector<cv::Point> > contours;
for( int c = 0; c < 3; c++ ) {
int ch[] = {c, 0};
mixChannels(&timg, 1, &gray0, 1, ch, 1);
for( int l = 0; l < N; l++ ) {
if( l == 0 ) {
cv::Canny(gray0, gray, 0, thresh, 5);
cv::dilate(gray, gray, cv::Mat(), cv::Point(-1,-1));
}
else {
gray = gray0 >= (l+1)*255/N;
}
cv::findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
}
}
cv::Mat pyr1, timg1, gray2(_image1.size(), CV_8U), gray1;
cv::pyrDown(_image1, pyr1, cv::Size(_image1.cols/2, _image1.rows/2));
cv::pyrUp(pyr1, timg1, _image1.size());
std::vector<std::vector<cv::Point> > contours1;
for( int c = 0; c < 3; c++ ) {
int ch[] = {c, 0};
mixChannels(&timg1, 1, &gray2, 1, ch, 1);
for( int l = 0; l < N; l++ ) {
if( l == 0 ) {
cv::Canny(gray2, gray1, 0, thresh, 5);
cv::dilate(gray1, gray1, cv::Mat(), cv::Point(-1,-1));
}
else {
gray1 = gray2 >= (l+1)*255/N;
}
cv::findContours(gray1, contours1, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
}
}
for( size_t i = 0; i < contours.size(); i++ )
{
double value= cv::matchShapes(contours[i], contours1[i], CV_CONTOURS_MATCH_I1, 0);
NSLog(#"%f",value);
}
}
UIImage *testImage = [UIImage imageNamed:#"note_with_marks (1).png"];
[self.imageView setImage:testImage];
cv::Mat forground = [testImage CVMat];
UIImage *testImage2 = [UIImage imageNamed:#"1.png"];
cv::Mat forground2 = [testImage2 CVMat];
[self tryingMatchShapes:forground _image1:forground2];
The app is getting crashed.
Error:-
OpenCV Error: Assertion failed (contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0 && (contour1.depth() == CV_32F || contour1.depth() == CV_32S) && contour1.depth() == contour2.depth()) in matchShapes, file /Users/Aziz/Documents/Projects/opencv_sources/trunk/modules/imgproc/src/contours.cpp, line 1705
Please some body help me in implementing this method from coding point of view.
Please I need some coding help.I have already gone through I lot of theoretical concepts.
Thanks in advance!
std::vector<std::vector<cv::Point> > contours1;
You can't apply matchShapes to such type. You can apply it for each (one) contour, not for group (array) of contours. For example:
cv::matchShapes(contours[0], contours1[0], CV_CONTOURS_MATCH_I1, 0);
Related
I want to print that in the console:
*
**
***
**
*
so, my code is:
Scanner input = new Scanner(System.in);
int n = input.nextInt();
char c = '*';
if (1 < n && n < 20) {
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= row; col++) {
System.out.print(c);
}
System.out.println();
}
any proposals how to finish?
You want to print "* **". Write this:
System.out.print("* **");
If my answer is not that what you excpected, than give us more information. What is your actual problem. See StackOverflowFAQ
If n is your "*" length,below code:
if (1 < n && n < 20) {
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= row; col++) {
System.out.print(c);
}
System.out.println();
}
for (int row =1; row <= n; row++) {
for (int col = n-row; col >0 ; col--) {
System.out.print(c);
}
System.out.println();
}
}
In a .hash section, for some x, if chain[x] != SHN_UNDEF,
it should hold hash(name(bucket[x])) === hash(name(bucket[chain[x]])) % nbucket
But why it's not the case for my shared object file?
For example, name(bucket[224]) == "_ZN9VADEnergyD0Ev" whose (ELF hash % nbucket) is 224,
name(bucket[8]) == "speex_bits_write_whole_bytes" whose (ELF hash % nbucket) is 8,
but chain[224] == 8.
(the file is avalible here)
Or my code for reading elf is wrong?
nbucket = ((int *)hash)[0];
nchain = ((int *)hash)[1];
memcpy(bucket, hash + 8, nbucket * 4);
memcpy(succ, hash + nbucket * 4 + 8, nchain * 4);
for (i = 0; i < nbucket; i++) {
printf("%d %d\n", bucket[i], succ[i]);
if (bucket[i] && succ[i])
pred[succ[i]] = i;
}
printf("%d %d\n", nbucket, nchain);
#define sym_name(x, symtbl, strtbl) (strtbl + symtbl[x].st_name)
for (i = 0; i < nbucket; i++) {
if (pred[i] == 0) {
printf("=======\n");
for (j = i; j; j = succ[j]) {
char *sname = sym_name(bucket[j], dynsym, dynstr);
printf("%d,succ=%d ", j, succ[j]);
printf("%d:%s\n", _dl_elf_hash(sname) % nbucket, sname);
}
}
}
It's my fault. It should be
hash(name(bucket[x])) === hash(name(chain[bucket[x]])) % nbucket
and
nbucket = ((int *)hash)[0];
nchain = ((int *)hash)[1];
memcpy(bucket, hash + 8, nbucket * 4);
memcpy(succ, hash + nbucket * 4 + 8, nchain * 4);
for (i = 0; i < nbucket; i++) {
printf("%d %d\n", bucket[i], succ[i]);
if (bucket[i] && succ[i])
pred[succ[i]] = i;
}
printf("%d %d\n", nbucket, nchain);
#define sym_name(x, symtbl, strtbl) (strtbl + symtbl[x].st_name)
for (i = 0; i < nbucket; i++) {
printf("=======\n");
for (j = bucket[i]; j; j = succ[j]) {
char *sname = sym_name(j, dynsym, dynstr);
printf("%d,succ=%d ", j, succ[j]);
printf("%d:%s\n", _dl_elf_hash(sname) % nbucket, sname);
}
}
I make code to get and set alsa mixer volume:
snd_mixer_elem_t *elem = NULL;
long alsa_min, alsa_max, alsa_vol;
int alsa_get_volume( void )
{
long val;
assert (elem);
if (snd_mixer_selem_is_playback_mono(elem)) {
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &val);
return val;
} else {
int c, n = 0;
long sum = 0;
for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
if (snd_mixer_selem_has_playback_channel(elem, c)) {
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &val);
sum += val;
n++;
}
}
if (! n) {
return 0;
}
val = sum / n;
sum = (long)((double)(alsa_vol * (alsa_max - alsa_min)) / 100. + 0.5);
if (sum != val) {
alsa_vol = (long)(((val * 100.) / (alsa_max - alsa_min)) + 0.5);
}
return alsa_vol;
}
}
int alsa_set_volume( int percentdiff )
{
long volume;
alsa_get_volume();
alsa_vol += percentdiff;
if( alsa_vol > 100 ) alsa_vol = 100;
if( alsa_vol < 0 ) alsa_vol = 0;
volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + 0.5);
snd_mixer_selem_set_playback_volume_all(elem, volume + alsa_min);
snd_mixer_selem_set_playback_switch_all(elem, 1);
muted = 0;
mutecount = 0;
return alsa_vol;
}
I wont to make alsa mixer volume to changed by GtkVolumeButton. Tried this but when value from gtk button is changed up or down, alsa mixer always jumps to 100 %:
int gtk_volume_button_get_value (GtkWidget *button)
{
return (int) (gtk_scale_button_get_value(GTK_SCALE_BUTTON(button)) * 100);
}
void gtk_volume_button_set_value (GtkWidget *button, int value)
{
gtk_scale_button_set_value(GTK_SCALE_BUTTON(button), (gdouble) value / 100);
}
void volume_value_changed_cb(GtkVolumeButton *button, gpointer user_data)
{
int vol = (int)(gtk_volume_button_get_value(volume_button) + 0.5);
alsa_set_volume(vol);
}
Please help me to write a corect code for GtkVolumeButton.
Your problem has nothing to do with GtkVolume. In fact, it comes from you using two different approaches to handle volume. alsa_get_volume gives you an absolute sound level, which is an integer. One would expect alsa_set_volume to accept the same kind of value range. And that's how you use it in volume_value_changed_cb: « get the volume level of the volume control, between 0 and 100, and set it as current volume. ».
However, the implementation is completely different. It's implemented as if you wanted to tell it « add or substract x% of the current sound volume ». You get the current volume level and add that percentage, thus you're computing a relative sound level, not an absolute one. So, if your initial sound level is 50%, and you want to lower it to 45%, one would expect you'd call alsa_set_volume (45) to do it. But currently, calling alsa_set_volume (45) will set alsa_vol to 50 + 45 = 95%.
So you need to use absolute volume, not relative.
/* newvol: Desired volume level in the [0;100] range */
int alsa_set_volume (int newvol)
{
long volume;
alsa_vol = CLAMP(absvol, 0, 100);
volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + alsa_min);
snd_mixer_selem_set_playback_volume_all(elem, volume);
snd_mixer_selem_set_playback_switch_all(elem, 1);
muted = 0;
mutecount = 0;
return alsa_vol;
}
I am taking about 50 times as long as expected to loop through a simple assignment. My first reaction was that I had disordered my memory access in the arrays, resulting in cache misses. This doesn't seem the case, however.
The pixel value assignment and updating the arrays takes a dogs age. Do any one of you folks have an inclining as to why this is happening? (I am compiling for an iPod with an A4)
memset(columnSumsCurrentFrameA, 0, sizeof(unsigned int) * (_validImageWidth/numSubdivisions) );
memset(rowSumsCurrentFrameA, 0, sizeof(unsigned int) * (_validImageHeight/numSubdivisions) );
int pixelValue = 0;
int startingRow = 0;
int startingColumn = 0;
for (int i = 0; i < _validImageHeight/numSubdivisions; i++)
{
int index = (i + startingRow) * _imageWidth;
for( int j = 0; j < (_validImageWidth/numSubdivisions); j++)
{
pixelValue = imageData[index + startingColumn + j];
columnSumsCurrentFrameA[j] += pixelValue;
rowSumsCurrentFrameA[i] += pixelValue;
}
}
The result of _validImageWidth/numSubdivisions must be an integer, are you sure that is always the case?
Also, you should calculate _validImageWidth/numSubdivisions before entering the double loops, it's not safe to assume your compiler takes care of it.
int limit = _validImageHeight/numSubdivisions;
for (int i = 0; i < limit; i++)
{
int index = (i + startingRow) * _imageWidth;
for( int j = 0; j < limit; j++)
{
pixelValue = imageData[index + startingColumn + j];
columnSumsCurrentFrameA[j] += pixelValue;
rowSumsCurrentFrameA[i] += pixelValue;
}
}
I have used the following code for converting the bigint in decimal to bytearray (raw data), but I'm getting wrong result.
What is the mistake here?
I'm trying this in Apple Mac ( for Iphone app)
COMP_BYTE_SIZE is 4
Is there any bigendian/ little endian issue, please Help.
void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
{
int i, j, k = size-1;
check(x);
memset(data, 0, size); /* ensure all leading 0's are cleared */
for (i = 0; i < x->size; i++)
{
for (j = 0; j < COMP_BYTE_SIZE; j++)
{
comp mask = 0xff << (j*8);
int num = (x->comps[i] & mask) >> (j*8);
data[k--] = num;
if (k < 0)
{
break;
}
}
}
Thanks.
The argument size is at least x->size*4, ie. the target array is big enough? Also use
comp mask = (comp)0xff << (j*8);
num should be cast to uint8_t before copy
data[k--] = (uint8_t)num;