2016-11-24 4 views
0

Я новичок в openCV, я попал в образцы, представленные для Android.Обнаружение черных чернил на бумаге - Opencv Android

Мои цели - обнаружить цветные пятна, поэтому я начал с образца для определения цвета-блоба.

Я преобразовываю цветное изображение в оттенки серого, а затем пороговое значение с использованием двоичного порога.

Фон белый, капли черные. Я хочу обнаружить эти черные капли. Кроме того, я хотел бы нарисовать их контур в цвете, но я не могу это сделать, потому что изображение черно-белое.

Мне удалось выполнить это в оттенках серого, но я не предпочитаю, как контуры рисуются, это похоже на то, что цветовая толерантность слишком высока, а контур больше, чем фактический blob (может быть, капли слишком малы?). Я предполагаю, что эта «толерантность», о которой я говорю, имеет какое-то отношение к setHsvColor, но я не совсем понимаю этот метод.

Заранее благодарен! С наилучшими пожеланиями

UPDATE ПОДРОБНЕЕ

Изображение Я хочу отслеживать это чернильных расколов. Представьте себе белый лист бумаги с черными чернилами. Сейчас я делаю это в режиме реального времени (просмотр камеры). Фактическое приложение будет делать снимок и анализировать эту картину.

Как я уже говорил выше, я взял образец обнаружения цвета-blob (android) из репозитория openCV GitHub. И я добавить этот код в onCameraFrame метода (для того, чтобы превратить его в черно-белом в режиме реального времени) Convertion сделано так, я не возражаю, если чернила черные, синие, красные:

mRgba = inputFrame.rgba(); 
/**************************************************************************/ 
/** BLACK AND WHITE **/ 
// Convert to Grey 
Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA, 4); 

Mat blackAndWhiteMat = new Mat (H, W, CvType.CV_8U, new Scalar(1)); 
double umbral = 100.0; 
Imgproc.threshold(mRgba, blackAndWhiteMat , umbral, 255, Imgproc.THRESH_BINARY); 

// convert back to bitmap for displaying 
Bitmap resultBitmap = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888); 
blackAndWhiteMat.convertTo(blackAndWhiteMat, CvType.CV_8UC1); 
Utils.matToBitmap(blackAndWhiteMat, resultBitmap); 
/**************************************************************************/ 

Возможно, это не лучший способ, но он работает.

Теперь я хочу обнаружить черные капли (разрывы чернил). Я предполагаю, что они обнаружены, потому что Logcat (запись в журнале примера приложения) выдает количество обнаруженных контуров, но я не могу их видеть, потому что изображение черно-белое, и я хочу, чтобы контур был красным, например.

Вот пример изображения: - enter image description here

И вот что я получаю с помощью RGB (цвет-блоб обнаружения, как есть, не черно-белое изображение). Обратите внимание, что маленькие капли не обнаружены. (Можно ли их обнаружить? Или они слишком малы?) enter image description here

Благодарим за помощь! Если вам нужна дополнительная информация, я бы с удовольствием обновлять этот вопрос

UPDATE: GitHub репо образца цвета-шарикообразным обнаружения (второе изображение)

GitHub Repo of openCV sample for Android

+0

Привет, Ваш вопрос довольно неинформативные. Загрузите входные изображения и то, что привело к вашей обработке. Это поможет понять вопрос. В качестве примера см. Этот вопрос: http://stackoverflow.com/q/10168686/1874627 – saurabheights

+0

@saurabheights спасибо за ваш комментарий. Я обновлю вопрос с дополнительной информацией, а также фрагментами кода – sebasira

+0

Хорошо, есть несколько вещей, которые я могу предложить. Будь то маленькие или большие капли не должны быть проблемой, если есть хороший контраст. Если вы можете найти область, в которой большинство пикселей являются белыми (проверьте подключенный компонент), у вас будет область бумаги. В этом случае, если вы обнаружите, что субрегион будет черным (путь ниже средней интенсивности области бумаги), вы найдете все свои капли. Чтобы нарисовать контур, вам понадобится выпуклый корпус черной области. Кроме того, вы можете загрузить код (или ссылку на него) для того, как вы достигли второго вывода изображения. Уже поздно, так что завтра это проверит. Спасибо за хорошее обновление. – saurabheights

ответ

0

Решение основано на сочетании адаптивной Порог изображения и использование алгоритма подключенных компонентов.

Успение - Бумага является наиболее освещенной областью изображения, тогда как пятна чернил на бумаге являются самыми темными областями.

from random import Random 
import numpy as np 
import cv2 

def random_color(random): 
    """ 
    Return a random color 
    """ 
    icolor = random.randint(0, 0xFFFFFF) 
    return [icolor & 0xff, (icolor >> 8) & 0xff, (icolor >> 16) & 0xff] 

#Read as Grayscale 
img = cv2.imread('1-input.jpg', 0) 
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) 

# Gaussian to remove noisy region, comment to see its affect. 
img = cv2.medianBlur(img,5) 

#Find average intensity to distinguish paper region 
avgPixelIntensity = cv2.mean(img) 
print "Average intensity of image: ", avgPixelIntensity[0] 

# Generate mask to distinguish paper region 
#0.8 - used to ignore ill-illuminated region of paper 
mask = cv2.inRange(img, avgPixelIntensity[0]*0.8, 255) 
mask = 255 - mask 
cv2.imwrite('2-maskedImg.jpg', mask) 

#Approach 1 
# You need to choose 4 or 8 for connectivity type(border pixels) 
connectivity = 8 
# Perform the operation 
output = cv2.connectedComponentsWithStats(mask, connectivity, cv2.CV_8U) 
# The first cell is the number of labels 
num_labels = output[0] 
# The second cell is the label matrix 
labels = output[1] 
# The third cell is the stat matrix 
stats = output[2] 
# The fourth cell is the centroid matrix 
centroids = output[3] 

cv2.imwrite("3-connectedcomponent.jpg", labels) 
print "Number of labels", num_labels, labels 

# create the random number 
random = Random() 

for i in range(1, num_labels): 
    print stats[i, cv2.CC_STAT_LEFT], stats[i, cv2.CC_STAT_TOP], stats[i, cv2.CC_STAT_WIDTH], stats[i, cv2.CC_STAT_HEIGHT] 
    cv2.rectangle(cimg, (stats[i, cv2.CC_STAT_LEFT], stats[i, cv2.CC_STAT_TOP]), 
     (stats[i, cv2.CC_STAT_LEFT] + stats[i, cv2.CC_STAT_WIDTH], stats[i, cv2.CC_STAT_TOP] + stats[i, cv2.CC_STAT_HEIGHT]), random_color(random), 2) 

cv2.imwrite("4-OutputImage.jpg", cimg) 

входное изображение

The Input Image

Маска Изображение из порогов и инвертных операций.

Masked Image

Использование подключенного компонента.

CC Image

Наложение выход подключенного компонента на входном изображении.

Output Image

+0

После публикации я заметил большой оранжевый прямоугольник. Если вы хотите игнорировать его, это должна быть простая оценка области по сравнению с изображением. Или, как и проверка соотношения сторон, blob будет иметь одинаковую высоту/ширину. Один вопрос, для чего это? – saurabheights

+0

@sebasira Это часть эстетики, хе-хе. Зачем использовать черный ящик, когда вы можете использовать радугу! Кроме того, черный ящик вокруг черной чернильной капли не будет очень заметным. – saurabheights

+0

@sebasira: Не могли бы вы рассказать мне, как все прошло? Это точность, а также подводные камни? Не спешите отвечать, не спешите. – saurabheights

Смежные вопросы