Line scanning openCV - image-processing

below is a very simple code segment, but I am not able to understand why it is cribbing, can you please tell me what the error means:
CvSize iSize;
iSize= cvGetSize(I1);
CvLineIterator *iter ;
CvPoint p1,p2;
long *arrH = new long[iSize.height + 1];
long *arrV = new long [iSize.width + 1];
for( int i=0; i<=iSize.height;i++)
{
p1.y = i; p2.y=i;
p1.x = 0; p2.x=iSize.width;
arrH[i] =0;
int l = cvInitLineIterator(I1,p1,p2,iter,4,0);
for( int j=0;j<l;j++)
{
arrH[i]+=iter.ptr;
CV_NEXT_LINE_POINT(iter);
}
fprintf(f1,"%d \n",arrH[i]);
}
Errors of the form:
left of '.ptr' must have class/struct/union
how do I tackle them ?

I think this:
CvLineIterator *iter ;
Should be:
CvLineIterator iter ;
And this:
cvInitLineIterator(I1,p1,p2,iter,4,0);
Should be:
cvInitLineIterator(I1,p1,p2,&iter,4,0);

Related

Why am I getting wrong answer for this SPOJ Question

I still dont know weather I am allowed discuss Competetive Programming Doubts here, please let me know..
Can someone help me on this SPOJ question, I am getting wrong Answer:
https://www.spoj.com/problems/SPIKES/
I have tried all the test cases I could think of and the code always gives correct output.
Before posting it here, I also asked it in spoj forum but Its been two days, no one replies...
#include<bits/stdc++.h>
using namespace std;
// # = 35
// # = 64
// . = 46
// s = 115
// Using Dijkstra to find the path with minimum no. of Spikes
int n,m,j;
const int N = 100;
const int INF = 9;
vector<int> g[N];
int vis[N][N];
pair<int,int> dist[N][N];
vector<pair<int,int>> movements = {
{0,1},{0,-1},{1,0},{-1,0}
};
bool isvalid(int i, int j){
return i>=0 && j>=0 && i<n && j<m;
}
void bfs(int sourcei, int sourcej){
set<pair<int,pair<int,int>>> q;
q.insert({0,{sourcei,sourcej}});
dist[sourcei][sourcej] = {0,INF};
while(q.size()>0){
auto curr_v = *q.begin();
int curr_i = (curr_v.second).first;
int curr_j = (curr_v.second).second;
int spikes = curr_v.first;
q.erase(q.begin());
if(vis[curr_i][curr_j]) continue;
vis[curr_i][curr_j] = 1;
for(auto m : movements){
int child_i = curr_i + m.first;
int child_j = curr_j + m.second;
int spikec = spikes;
if(!isvalid(child_i,child_j)) continue;
if(g[child_i][child_j] == 115) spikec = spikes+1;
if(vis[child_i][child_j]) continue;
if(g[child_i][child_j]==35) continue;
if(dist[child_i][child_j].second > spikec){
dist[child_i][child_j] = {(dist[curr_i][curr_j].first +1),spikec};
q.insert({spikec , {child_i,child_j}});
}
}
}
}
int main(){
cin>>n>>m>>j;
int start_j,start_i;
int end_j,end_i;
for (int i = 0; i < N; ++i){
for (int j = 0; j < N; ++j){
dist[i][j].second = INF;
dist[i][j].first = 0;
}
}
for (int i = 0; i < n; ++i){
for (int j = 0; j < m; ++j){
char x; cin>>x;
g[i].push_back((int)x);
if(x=='#') {
start_i = i;
start_j = j;
}
if(x=='x'){
end_i = i;
end_j = j;
}
}
}
bfs(start_i,start_j);
// for (int i = 0; i < n; ++i){
// for (int j = 0; j < m; ++j){
// cout<<dist[i][j].first<<","<<dist[i][j].second<<" ";
// }cout<<endl;
// }
if(dist[end_i][end_j].second <= (int)j/2) cout<<"SUCCESS"<<endl;
else cout<<"IMPOSSIBLE"<<endl;
return 0;
}

Opencv Mat efficiency linearized by right triangle

How to efficiency linearized Mat (symmetric matrix) to one row by right triangle.
For example, when I have:
0aabbb
b0aaaa
ba0bba
bac0aa
aaaa0c
abcab0
and then from that I get:
aabbbaaaabbaaac
Something like this:
...
template<class T>
Mat SSMJ::triangleLinearized(Mat mat){
int c = mat.cols;
Mat row = Mat(1, ((c*c)-c)/2, mat.type());
int i = 0;
for(int y = 1; y < mat.rows; y++)
for(int x = y; x < mat.cols; x++) {
row.at<T>(i)=mat.at<T>(y, x);
i++;
}
return row;
}
...
Since data in your mat is just a 1d array stored in row.data you can do whatever you want with it. I don't think you will find anything more special (w/o using vectorized methods) than just copying from this array.
int rows = 6;
char data[] = { 0,1,2,3,4,5,
0,1,2,3,4,5,
0,1,2,3,4,5,
0,1,2,3,4,5,
0,1,2,3,4,5};
char result[100];
int offset = 0;
for (int i = 0; i < 5; offset += 5-i, i++) {
memcpy(&result[offset] , &data[rows * i + i + 1], 5 - i);
}
Or with opencv Mat it would be
int rows = mat.cols;
char result[100]; // you can calculate how much data u need
int offset = 0;
for (int i = 0; i < 5; offset += 5-i, i++) {
memcpy(&result[offset] , &mat.data[rows * i + i + 1], 5 - i);
}
Mat resultMat(1, offset, result);

Sampling custom float texture2D in HLSL

I am wondering how to actually sample the data I am passing to the shader file. I am using two methods, is it the same for both? Are there any resources online for me to actually read up on this sort of thing?
Compiling at 5.0 but the version number does not matter so much.
I have two methods to pass the data.
The first;
for( UINT row = 0; row < textureDesc.Height; row++ )
{
UINT rowStart = row * mappedResource.RowPitch;
for( UINT col = 0; col < textureDesc.Width; col++ )
{
//width * number of channels (r,g,b,a)
UINT colStart = col * 4;
pTexels[rowStart + colStart + 0] = 10.0f; // Red
pTexels[rowStart + colStart + 1] = 10.0f; // Green
pTexels[rowStart + colStart + 2] = 255.0f; // Blue
pTexels[rowStart + colStart + 3] = 255.0f; // Alpha
}
}
The second;
float elements[416][416];
int elementsCount = 416*416;
for( int i = 0; i < 416; i++ )
{
for( int k = 0; k < 416; k++ )
{
elements[i][k] = 0;
}
}
memcpy(mappedResource.pData, elements, sizeof(float) * elementsCount);
Seems that I missed an important part of all of this.
When creating a texture, in the texture description, the Format is the type that will be returned when the object is sampled. Many thanks to Drop for the help.

Navigate through Array by Pointer to Pointer

I have tried to move through array by double pointer. Here is the Code.
void pptr (int **sptr2,int **ptr2)
{
**ptr2 = (**sptr2 + 7); //Works Fine
*sptr2++; *ptr2++; //Probable problem Statement
**ptr2 = (**sptr2 + 7); //Not Workign
}
void ppointer (int *sptr,int *ptr)
{
pptr (&sptr,&ptr);
}
main()
{
int sour[2];
sour[0] = 40;
sour[1] = 50;
int var[2];
var[0] = 10;
var[1] = 20;
printf("befor change %d %d\n",var[0],var[1]);
ppointer(&sour[0],&var[0]);
printf("pointer to pointer change %d %d\n",var[0],var[1]);
}
I wish to update var in pptr function. I can use double pointer (**sptr,**pptr) to reference pointer (sptr,ptr) (which are pointing to array) into function. I am able to update first one but second one has no change. I think problem is with statement *sptr++ & *ptr++.
Please help me understand how can i navigate through array by double pointer.
Thank you
I think it is the compiler just being silly with the "*sptr++;" and the "*ptr++;"
void pptr (int **sptr2, int **ptr2)
{
**ptr2 = (**sptr2 + 7);
///////////////////////////////////////////////////////
*sptr2++; //This is the problem these two statements
*ptr2++;
///////////////////////////////////////////////////////
**ptr2 = (**sptr2 + 7);
}
Now however if you change it to "*sptr2 += 1;" and "*ptr += 1;" it then works
void pptr (int **sptr2, int **ptr2)
{
**ptr2 = (**sptr2 + 7);
///////////////////////////////////////////////////////
*sptr2 += 1; //Now no problem
*ptr2 += 1;
///////////////////////////////////////////////////////
**ptr2 = (**sptr2 + 7);
}
I dont really know why the compiler does this due to lack of experience of using the "variable++" operator, I just generally use "variable += 1" instead.

Mean image with two functions difference

I want process image so each pixel value will be mean of its value and 4 neighbours.
Created two different functions:
Mat meanImage(cv::Mat& inputImage)
{
Mat output;
Mat kernel(3,3,CV_32F,0.0);
kernel.at<float>(0,1) = 0.2;
kernel.at<float>(1,0) = 0.2;
kernel.at<float>(1,1) = 0.2;
kernel.at<float>(1,2) = 0.2;
kernel.at<float>(2,1) = 0.2;
filter2D(inputImage,output,-1,kernel);
return output;
}
and:
Mat meanImage2(Mat& inputImage)
{
Mat temp;
Mat output(inputImage.rows,inputImage.cols,inputImage.type());
copyMakeBorder(inputImage,temp,1,1,1,1,BORDER_REPLICATE);
CV_Assert(output.isContinuous());
CV_Assert(temp.isContinuous());
const int len = output.rows * output.cols * output.channels();
const int rowLenTemp = temp.cols * temp.channels();
const int twoRowLenTemp = 2 * rowLenTemp;
const int rowLen = output.cols * output.channels();
uchar* outPtr = output.ptr<uchar>(0);
uchar* tempPtr = temp.ptr<uchar>(0);
for(int i = 0; i < len; ++i)
{
const int a = 6 * (i / rowLen) + 3;
outPtr[i] = (tempPtr[i+rowLenTemp+a] + tempPtr[i+a] +
tempPtr[i+rowLenTemp+a+3] + tempPtr[i+rowLenTemp+a-3] +
tempPtr[i+twoRowLenTemp+a]) / 5;
}
return output;
}
I've assumed that the result will be the same. So I've compared images:
Mat diff;
compare(meanImg1,meanImg2,diff,CMP_NE);
printf("Difference: %d\n",countNonZero(diff));
imshow("diff",diff);
And get a lot off differences. What is the difference between this functions?
Edit:
Difference for lena image taken from Lena
Beware that when you do the sum of pixels, you add unsigned chars and you may overflow.
Test your code by casting these pixels values to int.
outPtr[i] = ((int)tempPtr[i+rowLenTemp+a] + (int)tempPtr[i+a] +
(int)tempPtr[i+rowLenTemp+a+3] + (int)tempPtr[i+rowLenTemp+a-3] +
(int)tempPtr[i+twoRowLenTemp+a]) / 5;
Edit: I'd rather code this like (assuming image type is uchar and it has 3 channels)
for (int r = 0; r < output.rows; r++)
{
uchar* previousRow = temp.ptr<uchar>(r) + 3;
uchar* currentRow = temp.ptr<uchar>(r+1) + 3;
uchar* nextRow = temp.ptr<uchar>(r+2) + 3;
uchar* outRow = output.ptr<uchar>(r);
for (int c = 0; c < 3*output.cols; c++)
{
int value = (int)previousRow[c] +
(int)currentRow[c-3] + (int)currentRow [c] + (int)currentRow[c+3] +
(int)nextRow [c];
outRow[c] = value / 5;
}
}

Resources