OpenCv 2.3 C - Как изолировать объект внутри изображения
У меня есть изображение как:
Я хочу удалить черные строки и столбцы вокруг числа. Итак, я хочу, чтобы результат:
я пытаюсь это:
void findX(IplImage* imgSrc,int* min, int* max){
int i;
int minFound=0;
CvMat data;
CvScalar maxVal=cvRealScalar(imgSrc->width * 255);
CvScalar val=cvRealScalar(0);
//For each col sum, if sum < width*255 then we find the min
//then continue to end to search the max, if sum< width*255 then is new max
for (i=0; i< imgSrc->width; i++){
cvGetCol(imgSrc, &data, i);
val= cvSum(&data);
if(val.val[0] < maxVal.val[0]){
*max= i;
if(!minFound){
*min= i;
minFound= 1;
}
}
}
}
void findY(IplImage* imgSrc,int* min, int* max){
int i;
int minFound=0;
CvMat data;
CvScalar maxVal=cvRealScalar(imgSrc->width * 255);
CvScalar val=cvRealScalar(0);
//For each col sum, if sum < width*255 then we find the min
//then continue to end to search the max, if sum< width*255 then is new max
for (i=0; i< imgSrc->height; i++){
cvGetRow(imgSrc, &data, i);
val= cvSum(&data);
if(val.val[0] < maxVal.val[0]){
*max=i;
if(!minFound){
*min= i;
minFound= 1;
}
}
}
}
CvRect findBB(IplImage* imgSrc){
CvRect aux;
int xmin, xmax, ymin, ymax;
xmin=xmax=ymin=ymax=0;
findX(imgSrc, &xmin, &xmax);
findY(imgSrc, &ymin, &ymax);
aux=cvRect(xmin, ymin, xmax-xmin, ymax-ymin);
//printf("BB: %d,%d - %d,%d\n", aux.x, aux.y, aux.width, aux.height);
return aux;
}
Так что я использую:
IplImage *my_image = cvLoad....
CvRect bb = findBB(my_image);
IplImage *new_image = cvCreateImage(cvSize(bb.width,bb.height), my_image->depth, 1);
cvShowImage("test",new_image);
это не работает хорошо, потому что я пытаюсь проверить, есть ли в новом изображении черные строки или столбцы, и они присутствуют. Что я могу сделать? Кто-нибудь может мне помочь? (Извините за мой английский!)
1 ответ
Один из способов сделать это - просто выполнить технику ограничительной рамки, чтобы обнаружить цифру, как показано на рисунке ниже:
Поскольку ваше изображение уже обработано, я использую технику ограничивающего прямоугольника намного проще.
После этой процедуры все, что вам действительно нужно сделать, - это установить ROI (область интереса) исходного изображения в области, определенной рамкой, для достижения эффекта кадрирования и выделения объекта:
Обратите внимание, что в полученном изображении есть одна дополнительная строка / столбец пикселей на границе, которые не являются белыми. Ну, они тоже не черные. Это потому, что я не использовал какой-либо пороговый метод для преобразования изображения в черно-белое изображение. Приведенный ниже код демонстрирует технику ограничивающего прямоугольника, выполняемую в версии изображения в градациях серого.
Это в значительной степени дорожная карта для достижения того, что вы хотите. В образовательных целях я делюсь кодом, который я написал, используя C++ интерфейс OpenCV. Я уверен, что вы способны преобразовать его в интерфейс C.
#include <cv.h>
#include <highgui.h>
#include <vector>
int main(int argc, char* argv[])
{
cv::Mat img = cv::imread(argv[1]);
// Convert RGB Mat to GRAY
cv::Mat gray;
cv::cvtColor(img, gray, CV_BGR2GRAY);
// Store the set of points in the image before assembling the bounding box
std::vector<cv::Point> points;
cv::Mat_<uchar>::iterator it = gray.begin<uchar>();
cv::Mat_<uchar>::iterator end = gray.end<uchar>();
for (; it != end; ++it)
{
if (*it) points.push_back(it.pos());
}
// Compute minimal bounding box
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
// Draw bounding box in the original image (debug purposes)
//cv::Point2f vertices[4];
//box.points(vertices);
//for (int i = 0; i < 4; ++i)
//{
//cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 1, CV_AA);
//}
//cv::imshow("box", img);
//cv::imwrite("box.png", img);
// Set Region of Interest to the area defined by the box
cv::Rect roi;
roi.x = box.center.x - (box.size.width / 2);
roi.y = box.center.y - (box.size.height / 2);
roi.width = box.size.width;
roi.height = box.size.height;
// Crop the original image to the defined ROI
cv::Mat crop = img(roi);
cv::imshow("crop", crop);
cv::imwrite("cropped.png", crop);
cvWaitKey(0);
return 0;
}