Jump to content
Compvision.ru
Sign in to follow this  
maxfashko

Работа с float изображением

Recommended Posts

День добрый. Ситуация поставила меня в тупик:

# имеем изображение
cv2.LUT(img_3ch,label_colours,result)
result = result.astype(float)/255

#теперь, чтобы работать с изображением его необходимо перевести в int
result_int = result.astype(int)

#в конечном итоге, какими бы преобразованиями я не пользовался, np заполняем массив нулями
result_int = result.astype(np.int64)

#конечной целью служит выделить контур на изображении
gray_image = cv2.cvtColor(result_int, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray_image, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

 

Share this post


Link to post
Share on other sites

Вероятно потому что при преобразовании во float вы делите все на 255 и переводите в интервал 0-1 ? :)

Share this post


Link to post
Share on other sites

Да, глупости пишу... :wacko:

Мне вот что не понятно, как выбрать определенный отрезок от найденного контура на изображении, чтобы затем с ним работать?

58dce2770d649_result_segment.PNG.86769eefce818960f3b585e48d11aa30.PNG

Например отрезок обведенный красным. Или есть гораздо более простой способ получить линию, разделяющую два цвета, для последующей аппроксимации?

Share this post


Link to post
Share on other sites
9 minutes ago, maxfashko said:

Например отрезок обведенный красным. Или есть гораздо более простой способ получить линию, разделяющую два цвета, для последующей аппроксимации?

Заблюрить и посчитать производную по Y?

Share this post


Link to post
Share on other sites
Только что, BeS сказал:

Заблюрить и посчитать производную по Y?

Я думал сделать это через контур,а затем у scipy есть sp.polyfit(). И если взять полином первой степени то получу прямую. 

Как реализовать Ваш метод не допонимаю

 

Share this post


Link to post
Share on other sites

В контуре еще найти нужно правильный кусок.

Можно попробовать так: применить морфологию (erode + dilate) это уберет мелкие детали, после размыть, Sobel, затем по порогу границу. Дальше собрать эти точки, и запихнуть в fitLine. 

  • Like 1

Share this post


Link to post
Share on other sites
Только что, Smorodov сказал:

В контуре еще найти нужно правильный кусок.

Можно попробовать так: применить морфологию (erode + dilate) это уберет мелкие детали, после размыть, Sobel, затем по порогу границу. Дальше собрать эти точки, и запихнуть в fitLine. 

Мы все это проделываем ведь с исходным изображением? Получается, что в  результате работы Sobel у меня не будет тогда контуров захватывающих границы изображения (верх, левая, правая)?

Как то это все тянет на долгие вычисления...

Share this post


Link to post
Share on other sites

Это проделывается с результатом сегментации. Ну если у вас есть уравнение прямой, и прямоугольник, думается не очень то сложно получить верхнюю половину и нижнюю.

Share this post


Link to post
Share on other sites
10 часов назад, Smorodov сказал:

Можно попробовать так: применить морфологию (erode + dilate) это уберет мелкие детали, после размыть, Sobel, затем по порогу границу. Дальше собрать эти точки, и запихнуть в fitLine.

В целом то, что у меня получилось похоже на правду, но со странностями. Я что-то упустил?

# -*- coding: utf-8 -*-
import numpy as np
import cv2
 
image = cv2.imread('../data/segment_video/igm_0.jpg')

img = cv2.dilate(image, np.ones((8,8), np.uint8), iterations = 1)
img = cv2.blur(img,(3,3))

img = cv2.Sobel(img,cv2.CV_8U,1,1,ksize=5)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
_, contours, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]

# then apply fitline() function
[vx,vy,x,y] = cv2.fitLine(cnt,cv2.DIST_L2,0,0.01,0.01)

# Now find two extreme points on the line to draw line
lefty = int((-x*vy/vx) + y)
righty = int(((gray.shape[1]-x)*vy/vx)+y)

#Finally draw the line
cv2.line(img,(gray.shape[1]-1,righty),(0,lefty),255,2)

cv2.imshow('result',img)
cv2.imshow('img',image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Линия вписывается в зависимости от blur, чем выше значение, тем точнее. 

Исходное, blur(3,3), blur (10,10)

igm_0.jpg.7651db1cbeb31b946944052d7f87154b.jpgline_3blur.jpg.65ec2e90f7d3e694908fd5b5147cdd03.jpgline_10blur.jpg.844b970f3e7e8dfb54c0f9bf993e67f5.jpg

Share this post


Link to post
Share on other sites

Я правильно понимаю, что это задача определения угла горизонта для беспилотника?

Share this post


Link to post
Share on other sites
2 часа назад, 2expres сказал:

Я правильно понимаю, что это задача определения угла горизонта для беспилотника?

Да, отклонения по крену

Share this post


Link to post
Share on other sites

А как будет с таким изображением?

max1.jpg.3816d050c91f83e08c5d978ca8268582.jpg или max.jpg.da1de978208e9aeae2e82c39f7309a7a.jpg

Share this post


Link to post
Share on other sites

Тут горизонт не просматривается :) 

Но можно RANSAC-ом найти прямые, или тем-же Хафом, или LSD, но RANSAC скорее всего будет лучше работать.

Кстати вот еще, из свежего: http://cvrs.whu.edu.cn/projects/cannyLines/

 

Share this post


Link to post
Share on other sites
21 час назад, Smorodov сказал:

Тут горизонт не просматривается :) 

Но можно RANSAC-ом найти прямые, или тем-же Хафом, или LSD, но RANSAC скорее всего будет лучше работать.

С креном понятно, разобрался, а что насчет тангажа? Как коеффицент угловой меры от пикселя выразить? Как расстояние пересчитать на угол раствора?

Share this post


Link to post
Share on other sites

Была подобная задача, но не угол нужно было определить, а расстояние на плоскости пройденное объектом, но одно к другому сводится. Решалась так:

1. задаем условно 4 точки на кадре 

2. Замеряем чему эти точки соответствует на плоскости (или какому углу)

3. рассчитываем коэффициенты для полинома второго порядка, решая систему уравнений

4. получаем результат.

Есть момент что чем ближе к краю кадра тем менее точно полином второго порядка соответствует реальным искажениям объективов. 

Share this post


Link to post
Share on other sites
9 часов назад, iskees сказал:

Была подобная задача, но не угол нужно было определить, а расстояние на плоскости пройденное объектом, но одно к другому сводится. Решалась так:

1. задаем условно 4 точки на кадре 

2. Замеряем чему эти точки соответствует на плоскости (или какому углу)

3. рассчитываем коэффициенты для полинома второго порядка, решая систему уравнений

4. получаем результат.

Есть момент что чем ближе к краю кадра тем менее точно полином второго порядка соответствует реальным искажениям объективов. 

Не до конца понял, как вычислить тангаж по Вашему методу. С креном все ясно:

Берем две точки прямой, характеризующую линию горизонта, отнимаем их и вычисляем arctan, переводя в градусы.

В случае расчета тангажа известно только расстояние между двумя прямыми: линией горизонта, которую мы получили аппроксимацией (неба, земли) и линией, характеризующей продольную ось бпла. По каким формулам происходит расчет?

58e0963fbe1ac_0989_006.jpg.b05fc141fba8db330c578ff366229b1c.jpg

 

Share this post


Link to post
Share on other sites

Ну так камера-то (как и человеческий глаз кстати) видит не в пикселях и не в метрах, а в угловых единицах. Есть угол зрения камеры по вертикали и по горизонтали, если смещаетесь на какое то расстояние от оптической оси камеры, то можно найти угол, он будет пропорционален расстоянию от центра изображения. Точное значение можно посчитать если учесть угол обзора, естественно, это верно если камера откалибрована.

  • Like 1

Share this post


Link to post
Share on other sites
5 часов назад, Smorodov сказал:

Ну так камера-то (как и человеческий глаз кстати) видит не в пикселях и не в метрах, а в угловых единицах. Есть угол зрения камеры по вертикали и по горизонтали, если смещаетесь на какое то расстояние от оптической оси камеры, то можно найти угол, он будет пропорционален расстоянию от центра изображения. Точное значение можно посчитать если учесть угол обзора, естественно, это верно если камера откалибрована.

Спасибо!

Share this post


Link to post
Share on other sites
12 часа назад, Smorodov сказал:

Точное значение можно посчитать если учесть угол обзора, естественно, это верно если камера откалибрована.

Имеется отснятое видео шахматной доски, камерой, которая будет использоваться (видео очень долго обрабатывает, пришлось взять только часть изображений из отснятого). Воспользовался программой для калибровки, расположенной по адресу:

opencv_dir/samples/cpp/tutorial_code/calib3d/camera_calibration/

https://yadi.sk/i/Bv0iUR9j3GahHm

Изменил конфиг только для расположения изображений калибровки. Настройки доски не менял. Получил на выходе xml файлик с конфигом https://yadi.sk/d/56EX60qE3Gagqp

Камера используется в Phantom 4 (4к)

В спецификациях производитель пишет:

Цитата
Sensor
1/2.3” Effective pixels:12 M
Lens
FOV ( Field Of View ) 94° 20 mm ( 35 mm format equivalent )
f/2.8
focus at ∞
ISO Range
100-3200(video) 100-1600(photo)
Electronic Shutter Speed
8 s to 1/8000 s
Max Image Size
4000 x 3000
Still Photography Modes
Single shot
Burst shooting: 3/5/7 frames
Auto Exposure Bracketing (AEB):
3/5 Bracketed frames at 0.7EV Bias
Time-lapse
HDR
Video Recording Modes
UHD: 4096×2160 (4K) 24 / 25p
3840×2160 (4K) 24 / 25 / 30p
2704×1520 (2.7K) 24 / 25 / 30p
FHD: 1920×1080
24 / 25 / 30 / 48 / 50 / 60 / 120p
HD: 1280×720 24 / 25 / 30 / 48 / 50 / 60p
Max. Bitrate Of Video Storage

То есть теперь для того чтобы мне найти вертикальный и горизонтальный углы обзора необходимо воспользоваться формулой:

H = 2*arctan(35/2*2.8)= arctan(12.5) = 85

Что-то не похоже на правду. Мне необходимо для расчета FOV брать данные, которые получены при калибровке? Если да, то как будет выглядеть процедура определения углов зрения?

Share this post


Link to post
Share on other sites

Похоже, что понял, как это дело должно выглядеть:

FOV(w) = arctan(W / fy)

FOV(h) = arctan(H / fx), где:

H - будет размер картинки

fx - значение из матрицы калибровки внутренних параметров

2.3815068922917403e+03 0. 1920

0. 2.3815068922917403e+03 1080

0. 0. 1.

Вот и получается, что мой угол обзора камеры равен 77,4 и 48,78. Вот только в даташите указано, что FOV = 94 (это я как понимаю диагональ), если посчитать мои значения, выйдет 91.7. Это нормально?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×