привет, я хотел бы использовать высотную проекцию, чтобы выбрать между областью определения области, которую мне нравится показывать, что я могу добавить в свой код, чтобы показать только двоичное изображение, имеющее два пика белого цвета ? звенья картины:opencv и значение проекции
ответ
следующий код на основе некоторых предположений о вашем коде:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
int main(int argc, char *argv[])
{
// src is 32bits
IplImage* src_original = cvLoadImage("picture.jpg",1);
//convert to grayscale! (very important)
IplImage *src = cvCreateImage(cvGetSize(src_original), IPL_DEPTH_8U, 1);
cvCvtColor(src_original, src, CV_RGB2GRAY);
// release the original image
cvReleaseImage(&src_original);
//paintx, painty son 8bits
IplImage* paintx=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U, 1);
IplImage* painty=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U, 1);
// this is going to set colour to black
cvZero(paintx);
cvZero(painty);
int* v=new int[src->width];
int* h=new int[src->height];
memset(v,0,src->width*4);
memset(h,0,src->height*4);
int x,y;
uchar s;
CvScalar t;
// counts pixels with bright<100 along each column ("black" pixels)
//
// | | | | | | |
// | | | | | | |
// v v v v v v v
for(x=0;x<src->width;x++)
{
for(y=0;y<src->height;y++)
{
s = (((uchar*)(src->imageData+src->widthStep*y))[x]); //changed because of 0xC0000005 return error
if(s < 100)
v[x]++;
}
}
// vertical projection
//(with this code, graphic grows up)
for(x=0;x<src->width;x++)
{
for(y=src->height-1; y >= src->height-v[x];y--)
{
t.val[0]=255;
cvSet2D(paintx,y,x,t);
}
}
// counts pixels with bright<100 along each row ("black" pixels)
//
// --------->
// --------->
// --------->
for(y=0;y<src->height;y++)
{
for(x=0;x<src->width;x++)
{
s = (((uchar*)(src->imageData+src->widthStep*y))[x]);
if(s < 100)
h[y]++;
}
}
// horizontal projection
// graphic grows from right to left
for(y=0;y<src->height;y++)
{
for(x=src->width-1; x>= src->width -h[y];x--)
{
t.val[0]=255;
cvSet2D(painty,y,x,t);
}
}
cvNamedWindow("projection_vertical",1);
cvShowImage("projection_vertical",paintx);
cvNamedWindow("projection_horiz",1);
cvShowImage("projection_horiz",painty);
// wait for a key
cvWaitKey(0);
// release the image
cvReleaseImage(&src);
cvReleaseImage(&paintx);
cvReleaseImage(&painty);
return 0;
}
первый Редактировать
Я изменил код, чтобы настроить его на I маг, который вы только что опубликовали.
2nd edit.
Считает блоки белых пикселей
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
int main(int argc, char *argv[])
{
// src is 32bits
IplImage* src_original = cvLoadImage("picture.jpg",1);
//convert to grayscale! (very important)
IplImage *src = cvCreateImage(cvGetSize(src_original), IPL_DEPTH_8U, 1);
cvCvtColor(src_original, src, CV_RGB2GRAY);
// release the original image
cvReleaseImage(&src_original);
//paintx, painty son 8bits
IplImage* paintx=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U, 1);
IplImage* painty=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U, 1);
// this is going to set colour to white
CvScalar c; c.val[0]=255;
cvSet(paintx,c);
cvSet(painty,c);
int* v=new int[src->width];
int* h=new int[src->height];
memset(v,0,src->width*4);
memset(h,0,src->height*4);
int x,y;
int is_prevwhite; //used to remember a change of colour
uchar s;
CvScalar t;
// counts blocks of pixels with bright>100 along each column ("white" blocks)
//
// | | | | | | |
// | | | | | | |
// v v v v v v v
for(x=0;x<src->width;x++)
{
is_prevwhite = 0;
for(y=0;y<src->height;y++)
{
s = (((uchar*)(src->imageData+src->widthStep*y))[x]); //changed because of 0xC0000005 return error
if(s > 100)
if (!is_prevwhite){
v[x]++;
is_prevwhite = 1;
}
else
if (is_prevwhite)
is_prevwhite = 0;
}
}
// vertical projection
//(with this code, graphic grows up)
for(x=0;x<src->width;x++)
{
for(y=src->height-1; y >= src->height-v[x];y--)
{
t.val[0]=0;
cvSet2D(paintx,y,x,t);
}
}
// counts blocks of pixels with bright>100 along each row ("white" blocks)
//
// --------->
// --------->
// --------->
for(y=0;y<src->height;y++)
{
is_prevwhite = 0;
for(x=0;x<src->width;x++)
{
s = (((uchar*)(src->imageData+src->widthStep*y))[x]);
if(s > 100)
if (!is_prevwhite){
h[y]++;
is_prevwhite = 1;
}
else
if (is_prevwhite)
is_prevwhite = 0;
}
}
// horizontal projection
// graphic grows from right to left
for(y=0;y<src->height;y++)
{
for(x=src->width-1; x>= src->width -h[y];x--)
{
t.val[0]=0;
cvSet2D(painty,y,x,t);
}
}
cvNamedWindow("projection_vertical",1);
cvShowImage("projection_vertical",paintx);
cvNamedWindow("projection_horiz",1);
cvShowImage("projection_horiz",painty);
// wait for a key
cvWaitKey(0);
// release the image
cvReleaseImage(&src);
cvReleaseImage(&paintx);
cvReleaseImage(&painty);
return 0;
}
извините AJ, он задрожал, когда я попытаюсь с вашим кодом, пожалуйста, добавьте изображение, если вы можете увидеть их – Butterflay
, что вы меняете в коде, пожалуйста? – Butterflay
Это займет имя файла напрямую. И согласно вашим снимкам экрана: теперь он подсчитывает черные пиксели, а не белые; графика растет наоборот (^ и <); и цвет обратный (чем больше черных пикселей есть вдоль столбца/строки, тем больше длина белой линии в проекции) –
Если вы хотите добавить изображение, вы должны загрузить его на внешний сайт (например, imgur.com). Затем скопируйте прямую ссылку и вставьте ее здесь. Сделайте это точно так, как это (без звезд): ! * [Имя] * (URL-адрес изображения) –
спасибо, что я добавлю его сейчас – Butterflay
- ссылка второго изображения, так что на двух изображениях, если изображение содержит в одном ряду белого пикселя у них один пик, если они содержат два ряда белых пикселей, у них два пика, поэтому мне нравится добавлять в свой код некоторый цикл, подобный этому (если граф изображений содержит +/- два пика, это тот, который мне нужен и показать его в окне, если не показывать его – Butterflay